ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring Boot] 상세페이지 만들기 / Optional / 예외처리
    Spring | SpringBoot 2024. 8. 12. 17:21


     

     

    - URL 파라미터

    @GetMapping("/detail/{id}")
    String detail() {
      return "detail.html";
    }

     

     

    - DB에서 글 뽑아서 html에 넣기

    @GetMapping("/detail/{id}")
    String detail() {
      var result = itemRepository.findById(1L);
      return "detail.html";
    }

    리포지토리.findById(1L) 이러면 id가 1인 행을 찾아온다는군요.

    참고로 숫자를 Long 타입으로 만들고 싶으면 뒤에 L 적으면 됩니다.

    이걸 변수에 저장해서 이제 html에 보내면 될거같은데 근데 var 자리에 타입은 뭘 넣어야하게요?

    모르겠으면 변수에 마우스 올려보면 됩니다. 

    Optional 이런 타입을 넣으라는군요.

     

     

     

    - Optional 타입

    Optional은 null일 수도 있고 아닐 수도 있다는 타입

    DB에서 찾은걸 왜 이런 타입으로 변형해주냐면

    가끔 DB에 id가 1인 행이 없을 수도 있는거 아닙니까?

    그럴 땐 null 혹은 텅빈 값이 아마 이 변수에 들어올겁니다.

    그래서 JPA 만든 사람이 null일수도 있으니까 조심해서 쓰라고 만들어준 타입

     

     

    @GetMapping("/detail/{id}")
    String detail() {
    
      Optional<Item> result = itemRepository.findById(1L);
      System.out.println(result.get());
      return "detail.html";
    }

    Optional 자료는 .get() 붙여야 안에 들어있는 자료가 나옵니다

    물론 result 변수가 비어있을 수 있기 때문에 그냥 .get() 하고 그러면 에러나고 동작이 멈출 수 있습니다.

    그래서 "만약에 result 안에 뭐가 있는 경우에만 .get() 해서 사용해라" 이렇게 쓰는게 안전하고 좋습니다

     

     

    @GetMapping("/detail/{id}")
    String detail() {
    
      Optional<Item> result = itemRepository.findById(id);
      if (result.isPresent()){
        System.out.println(result.get());
        return "detail.html";
      } else {
        return "~~~";
      }
    }

    Optional타입변수.isPresent() 라고 쓰면 result변수에 뭐가 들어있으면 true를 그 자리에 남겨줍니다.

    그래서 위처럼 쓰면 확실하게 값이 들어있을 경우에만 .get() 해서 데이터를 안전하게 사용할 수 있습니다.

     

     


    - 상세페이지 완성

    /detail/1로 접속하면 1번 상품

    /detail/2로 접속하면 2번 상품 가져오도록

     @GetMapping("/detail/{id}")
        String detail(@PathVariable Long id, Model model) {
    
            Optional<Item> result = itemRepository.findById(id);
            if (result.isPresent()){
                // 가져온 데이터 html에 넣기
                model.addAttribute("data", result.get());
                return "detail.html";
            } else {
                return "redirect:/list";
            }
        }

    (@PathVariable 타입 URL파라미터명) 이라고 잘 작명하면

    URL 파라미터 자리에 유저가 입력한 내용을 가져올 수 있습니다. (위에서 id를 가져올 수 있음 1번, 2번,,. 등)

     

     

    - 링크 만들기

    1번 상품에는 href="/detail/1"

    2번 상품에는 href="/detail/2"

    3번 상품에는 href="/detail/3" 이렇게 오도록

     

    href="/detail/현재상품의id"

    (list.html)
    <div class="card" th:each="i : ${items}">
        <img src="https://placehold.co/300">
        <h4 th:text="${i.title}">바지</h4>
        <a th:href="@{/detail/{id}(id=${i.id})}">링크</a>
        <p th:text="${i.price + '원'}">7억</p>
    </div>

    href 안에 변수나 서버에서 보낸 데이터를 넣고 싶으면 이렇게 하면 된다

    - 보통은 서버에서 보낸 변수를 넣고 싶으면 ${ } 안에 넣으면 되는데 근데 href안에는 @{ } 부터 시작하면 됩니다.

    - 문자는 작은 따옴표 안에 넣어도 됩니다.

    - 문자들을 합치고 싶으면 + 기호 쓰면 됩니다.

     

     

     

    - 예외상황 처리

    예를 들어 /detail/abc 이런 식으로 접속해보면

    abc를 Long타입으로 변환할려고 하는데 그건 불가능해서 아마 서버에서 에러가 납니다.

    에러가 나면 친절하게 기본 에러페이지로 안내해주는데 

    유저들에게 그런걸 보여주는 것 보다는 따로 에러페이지를 만들어두는게 좋습니다. 

     

     

     

     

    Thymeleaf를 설치해서 쓰는 경우에는 그냥 error.html 만들어두면 

    서버에서 에러가 발생하면 그 페이지로 자동으로 이동됩니다.

    이게 에러처리끝임

    (error.html)
    
    <div>에러페이지임</div>
    
    <!--에러정보들-->
    <p th:text="${status}"></p>
    <p th:text="${error}"></p>
    <p th:text="${path}"></p>
    <p th:text="${message}"></p>
    <p th:text="${exception}"></p>

     


     

    * 이글은 아래 강의를 참고해 작성했습니다. 

    https://codingapple.com/course/spring-boot-jpa/

     

    쉽게 배우는 Spring Boot & JPA - 코딩애플 온라인 강좌

      Next.js는 프론트엔드부터 서버까지 만들 수 있는 React기반 프레임워크입니다. 이것만 사용해도 풀스택 웹개발이 가능합니다.    Next.js 사용시 서버사이드 렌더링이 쉽기 때문에  React, Vue만 사

    codingapple.com

     

     

Designed by Tistory.