2 분 소요


통합으로 추가되는 기능

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


입력 폼 처리

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

렌더링 전
<input type="text" th:field="*{itemName}"/>

렌더링 후
<input type="text" id="itemName" name="itemName" th:value="*{itemName}"/>

등록 폼

th:object를 적용하려면 해당 오브젝트 정보를 먼저 넘겨주어야 한다.

Controller

@GetMapping("/add")
public String addForm(Model model) {
    model.addAttribute("item", new Item());
    return "form/addForm";
}

등록 폼이기 때문에 빈 오브젝트를 만들어서 뷰에 전달했다.


addForm.html

<form action="item.html" th:action th:object="${item}" method="post">
    <div>
        <label for="itemName">상품명</label>
        <input type="text" id="itemName" th:field="*{itemName}" class="form-control" placeholder="이름을 입력하세요">
    </div>

    <div>
        <label for="price">가격</label>
        <input type="text" id="price" th:field="*{price}" class="form-control"
        placeholder="가격을 입력하세요">
    </div>

    <div>
        <label for="quantity">수량</label>
        <input type="text" id="quantity" th:field="*{quantity}" class="form-control" placeholder="수량을 입력하세요">
    </div>
  • th:object="${item}": <form>에서 사용할 객체를 지정.
  • th:field="*{itemName}"
    • ${item.itemName}과 같다.
  • th:fieldid, name, value 속성으르 자동으로 만들어준다.
    • value=""
  • 따라서, id속성을 제거해도 자동으로 만들어준다.


요구사항 추가

ItemType.enum

상품 종류(ENUM)

public enum ItemType {

    BOOK("도서"), FOOD("식품"), ETC("기타");

    private final String description;

    ItemType(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }
}

DeliveryCode.class

배송 방식

/**
 * FAST: 빠른 배송
 * NORMAL: 일반 배송
 * SLOW: 느린 배송
 */
@Data
@AllArgsConstructor
public class DeliveryCode {
    private String code;
    private String displayName;
}
  • @AllArgsConstructor: 모든 필드 값을 파라미터로 받는 생성자를 만듦
  • codeFAST같은 시스템에서 전달하는 값, displayName빠른 배송같은 고객에게 보여주는 값.

Item.class

상품

private Long id;
private String itemName;
private Integer price;
private Integer quantity;

private Boolean open; //판매 여부
private List<String> regions; //등록 지역
private ItemType itemType; //상품 종류
private String deliveryCode; //배송 방식


체크 박스 - 단일1

addForm.html

<div class="form-check">
    <input type="checkbox" id="open" name="open" class="form-check-input">        
    <label for="open" class="form-check-label">판매 오픈</label>
</div>
  • 체크 박스를 체크하면 HTML Form에서 open=on이라는 값이 넘어간다.
  • 스프링은 on문자를 true타입으로 변환해준다.

[주의]
HTML에서 체크 박스를 선택하지 않고 폼을 전송하면 open이라는 필드 자체가 서버로 전송되지 않는다.(null)

이런 문제를 해결하기 위해 스프링 MVC는 히든 필드(_open)를 만들어서 전송하게 되면 체크를 해제했다고 인식할 수 있다.
히든 필드는 항상 전송되기 때문에 체크를 해제한 경우 open은 전송되지 않고, _open만 전송되어 스프링 MVC는 체크를 해제했다고 판단한다.


체크 해제를 인식하기 위한 히든 필드
<input type="hidden" name="_open" value="on"/>
(해제시 false값이 넘어간다.)

체크 박스 체크
open=on&_open=on
체크시 스프링 MVC가 open에 값이 있는 것을 확인하고 사용.(_open은 무시.)

미체크
_open=on
스프링 MVC가 _open만 있는 것을 확인하여 체크되지 않았다고 인식한다.
서버에서 boolean타입을 찍어보면 null이 아닌 false가 나오게된다.


체크 박스 - 단일2

addForm.html

<div class="form-check">
    <input type="checkbox" id="open" th:field="*{open}" class="form-check-input">
    <label for="open" class="form-check-label">판매 오픈</label>
</div>

타임리프를 사용하면 체크 박스의 히든 필드 부분도 해결해준다. HTML 결과를 보면 히든 필드 부분이 자동으로 생성되어 있다.

item.html

<div class="form-check">
    <input type="checkbox" id="open" th:field="${item.open}"
        class="form-check-input" disabled>
    <label for="open" class="form-check-label">판매 오픈</label>
</div>

item.html에는 th:object를 사용하지 않아 th:field="${item.open}"으로 적었다.


생성 결과

<div class="form-check">
<input type="checkbox" id="open" class="form-check-input" disabled 
    name="open" value="true" checked="checked">
 <label for="open" class="form-check-label">판매 오픈</label>
</div>

checked="checked"
타임리프의 th:field를 사용하면 값이 true인 경우 checked속성이 자동으로 추가된다.


<출처 : 인프런 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술(김영한)>

댓글남기기