스프링 MVC 2편 - 백엔드 웹 개발 활용 기술을 공부하고 정리하는 포스트입니다.


타임리프 스프링 통합

  • 타임리프는 크게 2가지 메뉴얼을 제공.
    • 기본 메뉴얼: https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html
    • 스프링 통합 메뉴얼: https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html
  • 타임리프는 스프링 없이도 동작하지만, 스프링과 통합을 위한 다양한 기능을 편리하게 제공
    -> 스프링으로 백엔드를 개발하는 개발자 입장에서 타임리프를 선택하는 하나의 이유

스프링 통합으로 추가되는 기능들

  • 스프링의 SpringEL 문법 통합
  • ${@myBean.doSomething()}처럼 스프링 빈 호출 지원
  • 편리한 폼 관리를 위한 추가 속성
    • th:object (기능 강화, 폼 커맨드 객체 선택)
    • th:field, th:errors, th:errorclass
  • 폼 컴포넌트 기능
    • checkbox, radio button, List 등을 편리하게 사용할 수 있는 기능 지원
  • 스프링의 메시지, 국제화 기능의 편리한 통합
  • 스프링의 검증, 오류 처리 통합
  • 스프링의 변환 서비스 통합(ConversionService)

설정 방법

  • 타임리프 템플릿 엔진을 스프링 빈에 등록 -> 타임리프용 뷰 리졸버를 스프링 빈으로 등록
    • https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html#the-springstandarddialect
    • https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html#views-and-viewresolvers
  • build.gradleimplementation 'org.springframework.boot:spring-boot-starter-thymeleaf'을 넣어주면
    -> Gradle은 타임리프와 관련된 라이브러리를 다운로드 받고, 스프링 부트는 앞서 설명한 타임리프와 관련된 설정용 스프링 빈을 자동으로 등록

입력 폼 처리

  • th:object : 커맨드 객체를 지정
  • *{...} : 선택 변수 식. th:object에서 선택한 객체에 접근
  • th:field
    • HTML 태그의 id, name, value 속성을 자동으로 처리
    • id : th:field에서 지정한 변수 이름과 동일
    • name : th:field에서 지정한 변수 이름과 동일
    • value : th:field에서 지정한 변수의 값을 사용

요구사항 추가

  • 판매 여부
    • 판매 오픈 여부
    • 체크 박스
  • 등록 지역
    • 서울, 부산, 제주
    • 체크 박스로 다중 선택
  • 상품 종류
    • 도서, 식품, 기타
    • 라디오 버튼으로 하나만 선택
  • 배송 방식
    • 빠른 배송
    • 일반 배송
    • 느린 배송
    • 셀렉트 박스로 하나만 선택

체크박스

  • 체크 박스를 체크하면 HTML Form에서 open=on이라는 값이 넘어감 -> 스프링은 on이라는 문자를 true타입으로 변환
  • 체크 박스를 선택하지 않고 전송하면 open이라는 필드 자체가 서버로 전송되지 않음
    • 히든 필드를 하나 만들어서, _open처럼 기존 체크 박스 이름 앞에 언더 스코어(_)를 붙여서 전송하면 체크를 해제했다고 인식
    • <input type="hidden" name="_open" value="on"/>
    • 히든 필드는 항상 전송
    • 체크를 해제한 경우 open은 전송되지 않고, _open만 전송되는데, 이 경우 스프링 MVC는 체크를 해제했다고 판단
  • 타임리프에서 폼 기능을 제공 -> 히든 필드를 추가하지 않아도 됨
    • <input type="checkbox" id="open" th:field="*{open}" class="form-check-input">
    • th:field="*{open}"를 사용
  • th:field를 사용하면, 값이 true인 경우 체크를 자동으로 처리 -> 체크가 안된 상태를 원하면 disabled를 사용하면 됨

체크박스 - 멀티

  • th:for="${#ids.prev('regions')}"
    • ids.prev(...), ids.next(...)
    • 멀티 체크 박스가 생성될 때 서로 다른 id를 가지도록 임의의 숫자가 붙게 만듬

라디오 버튼

  • 체크 박스는 수정 시 체크를 해제하면 아무 값도 넘어가지 않음 -> 별도의 히든 필드로 이런 문제를 해결.
  • 라디오 버튼은 이미 선택이 되어 있다면, 수정 시에도 항상 하나를 선택하도록 되어 있음 -> 체크 박스와 달리 별도의 히든 필드를 사용할 필요가 없음.

  • <div th:each="type : ${T(hello.itemservice.domain.item.ItemType).values()}">
    • 타임리프에서 ENUM에 직접 접근할 수 있음
    • 스프링EL 문법으로 ENUM의 values()를 호출하면 모든 정보가 배열로 반환됨

셀렉트 박스

  • <select th:field="*{deliveryCode}" class="form-select">