본문 바로가기
Spring/스프링 MVC

[스프링 MVC 1편] 7 - (3) 상품 목록 - 타임리프

by Poorm 푸름 2023. 12. 3.

 *  스프링 입문 = window, 스프링 MVC 1편 = Mac 으로 진행합니다

 *  섹션7 부터는 자바 17 버전으로 진행합니다

 *  진도 : 섹션7 - (4) ~ (6)

 *          : 자바 클래스명,         : 코드,         : 단축키

 

 

1. 상품서비스 HTML

 

해당 부분은 강의를 참고해주세요 간단해서 넘어갑니다 ~

<참고>

이렇게 정적 리소스가 공개되는 /resources/static 폴더에 HTML을 넣어두면 실제 서비스에서도 공개된다 
(지금처럼 공개할 필요없는 HTML을 두는 것은 주의)

 

 

2. 상품목록 - 타임리프

 

1) 컨트롤러 만들기
[ java/hello/itemservice/web/basic/BasicItemController ]

@Controller
@RequestMapping("/basic/items")
@RequiredArgsConstructor
public class BasicItemController {

    private final ItemRepository itemRepository;

    @GetMapping
    public String items(Model model){
        List<Item> items = itemRepository.findAll();
        model.addAttribute("items", items);
        return "basic/items";
    }

    @PostConstruct
    public void init(){
        itemRepository.save(new Item("itemA", 10000,10));
        itemRepository.save(new Item("itemB", 20000,20));
    }
}

- @Controller

 

- 요청 정보 매핑 @RequestMapping

 

  • 요청 정보를 매핑 (해당 URL이 호출되면 이 메서드가 호출 )

- @RequiredArgsConstructor

  • (command+N)_Constuctor 클릭 - @Autowired(= 생성자 하나면 생략가능) 넣은 코드의 줄임버전

  • 컨트롤러가 스프링빈에 등록되면서 스프링빈에 리포지토리 주입된다

- 리포지토리 생성 private final ~

 

- 모델 객체 생성 public String ~ (Model model)

 

  • 목록 전체 조회 List<Item> ~ findAll (option + command +v)
  • Model에 데이터 추가 .addAttribute()

- 뷰 반환

 

  • @Controller를 사용하면서 String으로 반환하면 [반환값 = 뷰의 논리적이름]

 

- 테스트 데이터 임의로 넣어보기 @PostContructor ~

 

 

2) 뷰 화면 타임리프로 만들기

위 컨트롤러에서 임의로 정한 테스트 데이터가 출력될 수 있도록 타임리프 만들어보자!

 

- resources/static/css에 bootstrap 파일넣기 (강의 참고)

- resources/static/html에 add, edit, item, items 파일넣기 (강의 참고)

- [resources/templates/basic/items]에서 타임리프 영역 수정하기 (강의 참고)

 

 

타임리프 사용 선언 

 

  • <html xmlns:th="http://www.thymeleaf.org">

 

속성 변경 - 절대 경로 추가

  • th:href="@{/css/bootstrap.min.css}"

    타임리프 뷰 템플릿을 거치게 되면 기존의 href를 날리고 설정한 th:xxx 값으로 동적 변경해 실행  

URL 링크  표현식

  • @{...} : URL 링크

 

속성 변경 - 상품 등록 폼으로 이동

 

  • th:onclick="|location.href='@{/basic/items/add}'|"

 

리터럴 대체

 

  • |...|: + 없이 문자와 표현식 이어주기 가능

 

반복 출력

 

  •  th:each

  • <tr th:each="item : ${items}">
    모델에 있는 items 데이터 item 변수에 넣기

 

변수 표현식

 

  •  ${...}

내용 변경

 

  •  th:text

  • <td th:text="${item.price}">10000</td>
    10000${item.price} 의 값으로 변경

URL 링크 표현식2

 

  • th:href="@{/basic/items/{itemId}(itemId=${item.id})}"

 

 

< 예시 >

<td><a href="item.html" th:href="@{/basic/items/{itemId}(itemId=${item.id})}" th:text="${item.id}">회원id</a></td>

 

-        : 기존 경로

-        : 렌더링 되면 열리는 치환 링크 경로

       : 데이터 들어가는 부분 (변수)

 

 

순수 HTML을 그대로 유지하면서 뷰 템플릿 사용할 수 있는 타임리프를 네츄럴 템플릿 (natural templates)라 한다 

 

 

3. 상품 상세

 

1) 컨트롤러에 추가
[ java/hello/itemservice/web/basic/BasicItemController ]

@GetMapping("/{itemId}")
public String item(@PathVariable("itemId") long itemId, Model model){
    Item item = itemRepository.findById(itemId);
    model.addAttribute("item",item);
    return "basic/item";
}

 

- @PathVariable ()

 

  • 넘어온 상품ID로 상품을 조회하고, 모델에 담아두고 뷰 템플릿 호출

 

- itemId, 모델 객체 생성 public String ~ (Model model)

 

  • id로 찾아서 상품 꺼내기 itemRepository.findById ~ (option + command +v)
  • Model에 데이터 추가 .addAttribute()

- 뷰 반환

 

  • @Controller를 사용하면서 String으로 반환하면 [반환값 = 뷰의 논리적이름]

 

 

2) 뷰 화면 타임리프로 만들기

 

- [resources/templates/basic/item]에서 타임리프 영역 수정하기 (강의 참고)

 

 

 타임리프 사용 선언 

<html xmlns:th="http://www.thymeleaf.org">

 

속성 변경 - 절대 경로 추가 / URL 링크  표현식

th:href="@{/css/bootstrap.min.css}"
  • 타임리프 뷰 템플릿을 거치게 되면 기존의 href를 날리고 설정한 th:xxx 값으로 동적 변경해 실행  
  • @{...} : URL 링크

속성 변경 - th:value

th:value="${item.id}"
th:value="${item.itemName}"
th:value="${item.price}"
th:value="${item.quantity}"
  • 모델에 있는 item 정보를 획득하고 프로퍼티 접근법으로 출력
     

속성 변경 - 상품 수정 폼으로 이동 / 상품 목록 폼으로 이동

th:onclick="|location.href='@{/basic/items/{itemId}/edit(itemId=${item.id})}'|"
th:onclick="|location.href='@{/basic/items}'|"

< 여기서 문제!! >

 

코드를 올바르게 넣었는데도 아래와 같이 에러가 뜬다면?!!

 

- 에러이유 -

스프링 부트 3.2.0부터 @PathValuable 사용할 때 -parameters 라는 자바 컴파일 옵션을 설정해야 파라미터 이름을 생략할 수 있다

intellij idea로 build 시 -parameters 옵션이 설정되어 있지 않기 때문에 안되고 gradle로 build 시에는 -parameters 옵션이 자동 설정되어서 실행은 가능하나 속도가 너무 느리다

 

- 해결책 -

https://docs.google.com/document/d/1j0jcJ9EoXMGzwAA2H0b9TOvRtpwlxI5Dtn3sRtuXQas/edit#heading=h.b1yk4ued1pxo

 

해결 방안1(권장)

애노테이션에 이름을 생략하지 않고 다음과 같이 이름을 항상 적어준다. 이 방법을 권장한다.

@RequestParam("username") String username

@PathVariable("itemId") long itemId