🔗 요구사항 확인하기
✏️ 로그 설치
- 요청이 정상적으로 도착됬는지 확인하기 위해 로그를 만들어준다.
@PostMapping("/add")
public String addItem(@ModelAttribute Item item, RedirectAttributes redirectAttributes) {
log.info("item.open = {}", item.getOpen());
Item savedItem = itemRepository.save(item);
redirectAttributes.addAttribute("itemId", savedItem.getId());
redirectAttributes.addAttribute("status", true);
return "redirect:/form/items/{itemId}";
}
✏️ V1. 순수 HTML 로 구현
📍 Web
- intput 타입을 체크박스로 설정 후 Label 로 항목을 만들어주었다.
- name 속성인 open 은 Itme 에 판매여부 필드와 연결된다.
<div>
<div class="form-check">
<input type="checkbox" id="open" name="open" class="form-check-input">
<label for="open" class="form-check-label">판매 오픈</label>
</div>
</div>
📍 출력물 확인
- 체크박스 체크
- 상품 등록에서 체크박스에 체크 후 등록을 하니 로그에 true 라고 잘 나왔다.
- 체크박스를 체크하면 HTML form 에서
on
이라는 값이 넘어가고, Spring 은 boolean 일 경우 on
을 true
로 변경시켜준다.
- ⚠️ Spring 의 타입 컨버터가 이 기능을 수행해준다.
INFO 45287 --- [nio-8080-exec-7] h.i.web.form.FormItemController
: item.open = true
- 체크박스 체크 X
- 이 경우 false 가 출력되길 기대했지만 parameter 에 아무 값도 넘어오지 않았고,
결국 로그엔 null 이라고 입력되었다.
INFO 45287 --- [nio-8080-exec-3] h.i.web.form.FormItemController
: item.open = null
📍 문제점
- 이 문제는 등록할 때는 괜찮지만 수정 할 때 체크했던 설정을 체크 해제하면 아무 parameter 가 요청되지 않기 때문에 true 인 상태로 값이 수정되지 않는 문제를 발생시킨다.
✏️ V2. 히든 필드 추가
📍 히든필드로 문제 해결
- input 타입을 hidden 으로 설정 후,
체크박스의 name 에 _ 를 앞에 붙여 name 속성으로 설정해주면 히든 필드가 만들어진다.
- 히든필드는 Spring MVC 에서 제공하는 기능이다.
- 체크박스가 체크가 되지 않을경우 히든필드는 체크박스의 name 파라미터로 false 를 넘겨주게 된다.
- open = on , _open = on ⇒ true
- open = null , _open = on ⇒ false
<div class="form-check">
<input type="checkbox" id="open" name="open" class="form-check-input">
<input type="hidden" name="_open" value="on"/>
<label for="open" class="form-check-label">판매 오픈</label>
</div>
📍 문제점
- 체크박스를 생성할 때 마다 히든필드를 추가해주어야하는 번거로움이 발생된다.
✏️ V3. Thymeleaf
🔗 th:field 와 선택변수 사용법
📍 th:field 로 문제 해결
id
, name
, 히든필드를 삭제하고 th:field
속성을 사용한다.
- form 태그에서 `
th:object="${item}"
를 선언해 주었기 때문에 선택변수 적용이 가능하다.
- 만약 object 선언이 없다면
${item.open}
으로 설정해주어야 한다.
<div class="form-check">
<input type="checkbox" th:field="*{open}" class="form-check-input">
<label for="open" class="form-check-label">판매 오픈</label>
</div>
📍 출력물 확인
- Thymeleaf 가
id
, name
, value
생성은 물론 히든필드까지 생성 시켜버린다.
<div class="form-check">
<input type="checkbox" class="form-check-input" id="open1" name="open" value="true">
<input type="hidden" name="_open" value="on"/>
<label for="open" class="form-check-label">판매 오픈</label>
</div>
✏️ 상품 상세 확인 페이지도 적용
- 상품 상세 페이지엔 object 선언이 없기 때문에 선택변수를 사용할 수 없다.
- 하지만 적당한 곳에 object 를 설정해주면 사용 가능하다.
- 상품 상세페이지는 수정을 못하게 막아두어야 되기 때문에
disabled
속성으로 수정을 막아두었다.
<div class="form-check">
<input type="checkbox"
th:field="${item.open}"
class="form-check-input"
disabled>
<label for="open" class="form-check-label">판매 오픈</label>
</div>
📍 소스 확인
- 소스를 확인하니
id
, name
, value
외에도 checke
속성이 추가되었다.
- 체크박스는
check
라는 속성이 있으면 체크가 되어서 랜더링 된다.
- 순수 HTML 에서는 개발자가 설정해주어야 하지만 thymeleaf 를 사용하면 신경쓰지 않아도 된다.
<div class="form-check">
<input type="checkbox"
class="form-check-input"
id="open1"
name="open"
value="true"
checked="checked"
disabled>
<label for="open" class="form-check-label">판매 오픈</label>
</div>