Thymeleaf [ 타임리프 ][2]

uuuu.jini·2022년 5월 13일
0
post-thumbnail

🐯 타임리프 - 스프링 통합과 폼 🐯

1. 타임리프 스프링 통합

추가되는 기능

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

스프링 부트에서의 자동화

타임리프를 템플릿 엔진으로 스프링 빈에 등록하려면, 타임리프 용 뷰 리졸버를 스프링 빈으로 등록해야 한다.

스프링 부트에서는 build.gradle에 타임리프 관련 의존성만 추가해주면 관련 설정을 모두 자동으로 스프링 빈으로 등록해준다.

implementation'org.springframework.boot:spring-boot-starter-thymeleaf`

그리고 대부분의 타임리프 관련 설정은 application.properties에 추가해 설정 및 변경이 가능하다.


2. 입력 폼 처리

타임리프 속성을 이용해 입력 폼을 효율적으로 개선할 수 있다.

사용법

  • th:obejct : 커맨드 객체를 지정한다.
  • *{...} : 선택 변수 식으로 상위 태그의 th:object 에서 선택한 객체에 접근한다.
  • th:field : HTML 태그의 id,name,value 속성을 자동으로 처리해준다.
<input type="text" th:field="*{itemName}"/>
<!-- 렌더링  --!>
<input type="text" id="itemName" name="itemName" value="*{itemValue}" />

3. 요구사항 추가

폼에서 체크박스, 라디오 버튼, 셀렉트 박스를 타임리프를 이용하면 편리하게 사용할 수 있다.

3.1 ] 단일 체크박스 1

HTML checkbox 주의점

HTML checkbox의 특징으로 check 가 되지 않는다면 클라이언트에서 서버로 값을 보내지 않는다.

<input type="checkbox" id="open" name="open" class="form-check-input" />

위와 같은 태그가 있다고 할때 내가 선택을 하지 않은 경우에 open이라는 프로퍼티가 false가 아니라 아예 전송이 되지 않으므로 null 상태이다.
( check를 하면 on이라는 값이 넘어가는데 이를 스프링에서 true로 변경해주며 해당 역할을 스프링 컨버터가 수행한다.)

이러한 특징은 수정의 경우 문제가 될 수 있다. 사용자가 의도적으로 체크를 하지 않고 저장을 할 경우 아무 값도 넘어가지 않기 때문에 서버 구현에 따라 값이 변경되지 않을 수 있다. (선택 -> 선택해제 )

히든 필드를 이용한 해결

스프링 MVC는 히든 필드를 이용해 이러한 문제를 해결한다.

기존 체크박스 태그 앞에 히든 필드를 하나 추가하고 _open과 같이 언더스코어(_)를 붙혀 전송하면 체크를 해제했음을 인식할 수 있다. 히든필드는 항상 전송된다는 점을 노린 방식인데, 체크를 해제한 경우 open은 전송되지 않고 _open만 전송되는데 이러한 경우를 스프링은 체크가 해제되었다고 판단한다.

  • 체크 해제를 위한 히든 필드
<input type="hidden" name="_open" value="on" />
  • 기존 checkbox 코드에 히든 필드 추가
<input type="hidden" name="_open" value="on">
<input type="checkbox" id="open" name="open" class="form-check-input" />

이렇게 작성하면 체크박스를 선택하지 않아도 서버에서 null값이 아니라 명확하게 false를 받을 수 있다. 이는 스프링 MVC에서 _open만 존재하는 것을 확인 후 체크되지 않았음을 인식한다.

3.2] 단일 체크박스2

히든필드는 타임리프의 폼 기능을 사용해 자동으로 생성해줄 수 있다. th:field 속성을 이용하면 id,name,value,field뿐 아니라 hidden field와 checked속성까지 자동으로 설정해준다.

  • Object.open의 값은 true이다.
  • 렌더링 전 체크박스
<input type="checkbox" th:field="*{open}" />
  • 렌더링 후 체크박스
<input type="checkbox" id="open" name="open" th:value="true" checked="checked" />
<input type="hidden" name="_open" value="on">

3.3 ] 멀티 체크 박스

체크 박스를 멀티로 사용하여 하나 이상을 나타나게 할 수도 있고 체크할수도 있게 할 수 있다.

@ModelAttribute의 또다른 사용법

: 보통 API 의 Request로 사용하는 이 어노테이션을 붙여주면 해당 메서드의 반환값이 자동으로 Model에 담기게 된다.

@ModelAttribute("data")
public String data(){
	return "testData";
}

-> data라는 이름으로 해당 속성을 사용할 수 있고 testData가 값으로 사용된다.

사용법

  • 렌더링 전 타임리프 코드
<div>
  <div>등록지역</div>
  <div th:each="region : ${regions}"class = "form-check form-check-inline">
    <input type="checkbox" th:field="*{regions}" th:value="${region.key}" class="form-check-input" >
    <label th:for="${#ids.prev('regions')}" th:text="${region.value}" class="form-check-label"> 서울 </label>
  </div>
</div>
  • regions라는 반복 가능한 요소를 th:each로 반복하도록 선언한다.

  • th:field를 넣으면 th:value 값과 비교하여 값이 포함되면 checked가 추가된다. 즉, 자동으로 value와 비교해서 checked 여부를 설정할 수 있다.

  • th:for="${#ids.prev('regions')}" -> 멀티 체크박스는 같은 이름의 여러 체크박스가 생성된다. name은 동일해도 되지만 id는 모두 달라야 하므로 타임리프의 편의 목적으로 ids라는 프로퍼티를 제공하며 아래와 같은 메서드를 제공한다. ids는 반복하는 요소의 인덱스로 1,2,3처럼 숫자다.
    -> ids.prev(...) : 아이디 앞에 인수값을 문자열 결합해준다. ( Ex : ids.prev('data') - data1
    -> ids.next(...) : 아이디 뒤에 인수값을 문자열 결합해준다. ( Ex : ids.next('data') - 1data

3.4 ] 라디오 버튼

다중 선택이 안되는 라디오 버튼은 선택지 중 하나를 선택할 수 있다.

사용법

  • 표현할 라디오 버튼이 하나가 아닌 이상 th:each 속성을 이용해 반복한다.
  • 작성법 자체는 멀티 체크박스와 동일하다.
  • 예제 코드
<div th:obejct="${item}">
  ...
  <div th:each="type : ${itemTypes}" class="form-check form-check-	inline">
    <input type="radio" th:field="*{itemTypes}" th:value="${type.name()}"class="form-check-input">
    <label th:for="{#ids.prev('itemTypes')}" th:text="${type.description}" class="form-check-label">
      BOOK
    </label>
  </div>
</div>
  • 라디오 버튼은 여러 선택지 중 하나를 선택할 때 사용한다.
  • 라디오 버튼은 한번 선택하면 수정으로 값을 null로 바꾸지 못하기 때문에 히든 필드가 필요 없다.
  • 라디오 버튼에서 선택해서 저장하면 조회시에 해당 선택지에 'checked="checked"'속성이 추가되어 있다.

3.5 ] 셀렉트 박스

라디오 버튼과 비슷하게 여러 선택지 중 하나를 선택할 때 사용할 수 있다.

사용법

  • 반복요소가 있는 셀렉트박스 역시 th:each로 요소를 반복하며 하나하나의 값을 다룬다.
  • 수정페이지에서 기본으로 선택되어야 하는 값이 있다면 th:field 요소를 이용해 가능하다.
  • 예제

        <div>
            <div>배송 방식</div>
            <select th:field="*{deliveryCode}" class="form-select">
                <option value="">==배송 방식 선택==</option>
                <option th:each="deliveryCode : ${deliveryCodes}" th:value="${deliveryCode.code}"
                        th:text="${deliveryCode.displayName}">FAST</option>
            </select>
        </div>

-> select 태그에 선언된 th:field속성과 option에서 선언된 th:value를 타임리프가 비교해 일치할 경우 자동으로 selected 된다.

profile
멋쟁이 토마토

0개의 댓글