코딩성장스토리

스프링 타임리프 스프링 통합기능 본문

백 엔드/spring

스프링 타임리프 스프링 통합기능

까르르꿍꿍 2022. 5. 6. 02:06

김영한 선생님의 MVC2편 정리

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

스프링의 SpringEL 문법 통합

  1. ${@myBean.doSomething()} 처럼 스프링 빈 호출 지원

편리한 폼 관리를 위한 추가 속성

  1. th:object (기능 강화, 폼 커맨드 객체 선택)
  2. th:field , th:errors , th:errorclass

폼 컴포넌트 기능

  1. checkbox, radio button, List 등을 편리하게 사용할 수 있는 기능 지원

스프링의 메시지, 국제화 기능의 편리한 통합

스프링의 검증, 오류 처리 통합

스프링의 변환 서비스 통합(ConversionService)

 

입력폼 기능

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

 

th:object="${item}" : 에서 사용할 객체를 지정한다.

선택 변수 식( *{...} )을 적용할 수 있다.

th:field="*{itemName}"

*{itemName} 는 선택 변수 식을 사용했는데, ${item.itemName} 과 같다. 앞서 th:object 로 item 을 선택했기 때문에 선택 변수 식을 적용할 수 있다.

th:field 는 id , name , value 속성을 모두 자동으로 만들어준다.

id : th:field 에서 지정한 변수 이름과 같다. id="itemName"

name : th:field 에서 지정한 변수 이름과 같다. name="itemName"

value : th:field 에서 지정한 변수의 값을 사용한다. value=""

 

참고로 해당 예제에서 id 속성을 제거해도 th:field 가 자동으로 만들어준다

 

체크박스 

단일

체크 박스를 체크하면 HTML Form에서 (변수 boolean)open=on 이라는 값이 넘어간다.

스프링은 on 이라는 문자를 true 타입으로 변환해준다

HTML checkbox는 선택이 안되면 클라이언트에서 서버로 값 자체를 보내지 않는다. 수정의 경우에는 상황에 따라서 이 방식이 문제가 될 수 있다. 사용자가 의도적으로 체크되어 있던 값을 체크를 해제해도 저장시 아무 값도 넘어가지 않기 때문에, 서버 구현에 따라서 값이 오지 않은 것으로 판단해서 값을 변경하지 않을 수도 있다.

이를 해결하기 위해 히든 필드가 사용이 된다. 체크되지 않으면 반드시 넘어온다 그리고 이것이 넘어오면 true가 아닌 false로바뀐다.

<input type="hidden" name="_open" value="on"/>

하지만 이 히든필드를 자꾸 넣어주면 귀찮다 

이럴 떄 타임리프의 th:field 가 효력을 발휘한다

<input type="checkbox" id="open" th:field="*{open}" class="form-checkinput">

이 기능을 사용하면 히든필드가 자동으로 삽입이 된다.

또한,

checked="checked"

체크 박스에서 판매 여부를 선택해서 저장하면, 조회시에 checked 속성이 추가된 것을 확인할 수 있다. 이런 부분을 개발자가 직접 처리하려면 상당히 번거롭다. 타임리프의 th:field 를 사용하면, 값이 true 인 경우 체크를 자동으로 처리해준다.

 

멀티

@ModelAttribute의 특별한 사용법

예)

@ModelAttribute("regions")
public Map<String, String> regions() {
 Map<String, String> regions = new LinkedHashMap<>();
 regions.put("SEOUL", "서울");
 regions.put("BUSAN", "부산");
 regions.put("JEJU", "제주");
 return regions;
}

@ModelAttribute 는  컨트롤러에 있는 별도의 메서드에 적용할 수 있다. 이렇게하면 해당 컨트롤러를 요청할 때 regions 에서 반환한 값이 자동으로 모델( model )에 담기게 된다. 

체크박스 멀티로 만들기

<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
th:for="${#ids.prev('regions')}"

멀티 체크박스는 같은 이름의 여러 체크박스를 만들 수 있다. 그런데 문제는 이렇게 반복해서 HTML 태그를 생성할 때, 생성된 HTML 태그 속성에서 name 은 같아도 되지만, id 는 모두 달라야 한다. 위의 기능은  체크박스를 each 루프 안에서 반복해서 만들 때 임의로 1 , 2 , 3 숫자를 뒤에 붙여준다.

 

서울, 부산 선택  regions=SEOUL&_regions=on(선택)&regions=BUSAN&_regions=on(선택)&_regions=on (선택안됨)로그 이걸로 체크 되었는지 판단 히든필드 삽입된다.

 

라디오버튼

 

enum 배열

@ModelAttribute("itemTypes")
public ItemType[] itemTypes() {
 return ItemType.values();
}

ItemType.values() 를 사용하면 해당 ENUM의 모든 정보를 배열로 반환한다

package hello.itemservice.domain.item;
public enum ItemType {
    BOOK("도서"), FOOD("식품"), ETC("기타");
    private final String description;
    ItemType(String description) {
        this.description = description;
    }
    public String getDescription() {
        return description;
    }
}

열거형 생성자를 이용해서 만들었다. 생성하면 description에는 한글로 되어있는부분이 담긴다.

<div>
 <div>상품 종류</div>
 <div th:each="type : ${itemTypes}" class="form-check form-check-inline">
 <input type="radio" th:field="*{itemType}" th:value="${type.name()}"
class="form-check-input">
 <label th:for="${#ids.prev('itemType')}" th:text="${type.description}"
class="form-check-label">
 BOOK
 </label>
 </div>
</div>

description은 타임리프 특성상 type.getdescription 으로 된다. 그래서 한글로 나오게 된다 . name()은 book,food 같은 열거형 변수들을 string으로 변환하여 나오게 한다. 

 

 

셀렉트 박스

 

밑에 코드들을 보자

@ModelAttribute("deliveryCodes")
public List<DeliveryCode> deliveryCodes() {
 List<DeliveryCode> deliveryCodes = new ArrayList<>();
 deliveryCodes.add(new DeliveryCode("FAST", "빠른 배송"));
 deliveryCodes.add(new DeliveryCode("NORMAL", "일반 배송"));
 deliveryCodes.add(new DeliveryCode("SLOW", "느린 배송"));
 return deliveryCodes;
}
<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>

checked="checked" 나 selected="selected" 는 th:field와 th:value 값을 비교해서 있으면 저 구문이 형성이 된다.

'백 엔드 > spring' 카테고리의 다른 글

스프링 vaildation  (0) 2022.05.09
스프링 메시지,국제화  (0) 2022.05.06
spring 타임리프 기본기능  (0) 2022.05.05
스프링 이해를 위한 디자인 패턴  (0) 2022.04.08
스프링 토이 프로젝트 진행중에 배운것  (0) 2022.03.14