스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 6

Spring 정리 2022. 6. 12. 17:18

인프런 강의 45일차.

 - 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 1 (김영한 강사님)

 - 1편에서 배운 MVC를 활용할 수 있는 기술 습득

 - 타입 컨버터, 파일 업로드, 활용, 쿠키, 세션, 필터, 인터셉터, 예외 처리, 타임리프, 메시지, 국제화, 검증 등등

 

2. 타임리프 - 스프링 통합과 폼

 2.7 라디오 버튼

  - 라디오 버튼은 여러 선택지 중에 하나를 선택할 때 사용할 수 있다. 라디오 버튼을 자바 ENUM을 활용해서 개발

  - 상품 종류

    > 도서, 식품, 기타

    > 라디오 버튼으로 하나만 선택할 수 있다

 

@ModelAttribute("itemTypes")
public ItemType[] itemTypes() {
    return ItemType.values();   //enum.values()는 enum 데이터를 배열로 넘겨준다.
}

  - hello.itemservice.web.form.FormItemController.java

  - enum 데이터를 배열로 리턴하는 itemType 메소드 추가

  - itemTypes 를 등록 폼, 조회, 수정 폼에서 모두 사용하므로 @ModelAttribute 의 특별한 사용법을 적용하자.

  - ItemType.values() 를 사용하면 해당 ENUM의 모든 정보를 배열로 반환한다. 예) [BOOK, FOOD, ETC]

 

<!-- 2.7 라디오 버튼 -->
<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>

  - resources/templates/form/addForm.html

  - 라디오 버튼을 구현한 등록 form HTML

  - 라디오 버튼은 이미 선택이 되어 있다면, 수정 시에도 항상 하나를 선택하도록 되어 있으므로 체크 박스와 달리 별도의 히든 필드를 사용할 필요가 없다.

 

 

  *  실행 결과, 폼 전송

itemType=FOOD //음식 선택, 선택하지 않으면 아무 값도 넘어가지 않는다.

 

  *  로그 추가

log.info("item.itemType={}", item.getItemType());

 

  * 실행 로그

item.itemType=FOOD   : 값이 있을 때
item.itemType=null   : 값이 없을 때

 

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

  - resources/templates/form/item.html

  - 상품 상세 form에 라디오 버튼 추가

  - item.html 에는 th:object 를 사용하지 않았기 때문에 th:field 부분에 ${item.itemType} 으로 적어주어야 한다.

  - disabled 를 사용해서 상품 상세에서는 라디오 버튼이 선택되지 않도록 했다

 

<!-- 2.7 라디오 버튼 -->
<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>

  - resources/templates/form/editForm.html

  - 상품 수정 form에 라디오 버튼 추가.

 

  * 렌더링 후 결과 HTML

<!-- 타임리프로 생성된 HTML -->
<div>
    <div>상품 종류</div>
    <div class="form-check form-check-inline">
        <input type="radio" value="BOOK" class="form-check-input" id="itemType1" name="itemType">
        <label for="itemType1" class="form-check-label">도서</label>
    </div>
    <div class="form-check form-check-inline">
        <input type="radio" value="FOOD" class="form-check-input" id="itemType2" name="itemType" checked="checked">
        <label for="itemType2" class="form-check-label">식품</label>
    </div>
    <div class="form-check form-check-inline">
        <input type="radio" value="ETC" class="form-check-input" id="itemType3" name="itemType">
        <label for="itemType3" class="form-check-label">기타</label>
    </div>
</div>

  - 선택한 식품( FOOD )에 checked="checked" 가 적용된 것을 확인할 수 있다.

 

  * 타임리프에서 ENUM 직접 사용하기

<!-- 타임리프에서 enum 직접 접근 -->
<div th:each="type : ${T(hello.itemservice.domain.item.ItemType).values()}">

  - 스프링EL 문법으로 ENUM을 직접 사용할 수 있다.

  - ENUM에 values() 를 호출하면 해당 ENUM의 모든 정보가 배열로 반환된다.

  - ENUM의 패키지 위치가 변경되면 자바 컴파일러가 타임리프까지 컴파일 오류를 잡을 수 없으므로 추천하지는 않는다.

 

 

 2.8 셀렉트 박스

  - 라디오 버튼은 여러 선택지 중에 하나를 선택할 때 사용할 수 있다. 라디오 버튼을 자바 ENUM을 활용해서 개발

  - 배송 방식

    > 빠른 배송

    > 일반 배송

    > 느린 배송

    > 셀렉트 박스로 하나만 선택할 수 있다.

@ModelAttribute("deliveryCodes")
public List<DeliveryCode> deliveryCodes() {
    //enum 대신 자바 객체를 사용하는 방법
    List<DeliveryCode> deliveryCodes = new ArrayList<>();
    deliveryCodes.add(new DeliveryCode("FAST", "빠른 배송"));
    deliveryCodes.add(new DeliveryCode("NORMAL", "일반 배송"));
    deliveryCodes.add(new DeliveryCode("SLOW", "느린 배송"));
    return deliveryCodes;
}

  - hello.itemservice.web.form.FormItemController.java

  - enum 대신 java 객체로 리턴하는 deliveryCodes 메소드 추가

  - DeliveryCode 를 등록 폼, 조회, 수정 폼에서 모두 사용하므로 @ModelAttribute 의 특별한 사용법을 적용하자.

  - @ModelAttribute 가 있는 deliveryCodes() 메서드는 컨트롤러가 호출 될 때 마다 사용되므로 deliveryCodes 객체도 계속 생성된다. 이런 부분은 미리 생성해두고 재사용하는 것이 더 효율적이다. (예시는 단순하게 매번 생성해버림)

 

<!-- 2.8 셀렉스 박스 -->
<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>

  - resources/templates/form/addForm.html

  - 셀렉트 박스를 구현한 등록 form HTML

 

  * 렌더링 후 결과 HTML

<!-- 2.8 셀렉스 박스 -->
<div>
    <DIV>배송 방식</DIV>
    <select class="form-select" id="deliveryCode" name="deliveryCode">
        <option value="">==배송 방식 선택==</option>
        <option value="FAST">빠른 배송</option>
        <option value="NORMAL">일반 배송</option>
        <option value="SLOW">느린 배송</option>
    </select>
</div>

 

 

<!-- 2.8 셀렉스 박스 -->
<div>
    <div>배송 방식</div>
    <select th:field="${item.deliveryCode}" class="form-select" disabled>
        <option value="">==배송 방식 선택==</option>
        <option th:each="deliveryCode : ${deliveryCodes}" th:value="${deliveryCode.code}"
                th:text="${deliveryCode.displayName}">FAST</option>
    </select>
</div>

  - resources/templates/form/item.html

  - 상품 상세 form에 셀렉트 박스 추가

 

<!-- 2.8 셀렉스 박스 -->
<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>

  - resources/templates/form/editForm.html

  - 상품 수정 form에 셀렉스 박스 추가

 

  * 렌더링 후 결과 HTML

<!-- 2.8 셀렉스 박스 -->
<div>
    <DIV>배송 방식</DIV>
    <select class="form-select" id="deliveryCode" name="deliveryCode">
        <option value="">==배송 방식 선택==</option>
        <option value="FAST" selected="selected">빠른 배송</option>
        <option value="NORMAL">일반 배송</option>
        <option value="SLOW">느린 배송</option>
    </select>
</div>

  - 빠른 배송을 선택했을 경우 selected="selected" 속성이 추가된 것을 확인할 수 있다.