이 영역을 누르면 첫 페이지로 이동
천천히 꾸준히 조용히 블로그의 첫 페이지로 이동

천천히 꾸준히 조용히

페이지 맨 위로 올라가기

천천히 꾸준히 조용히

천천히 꾸준히 조용히.. i3months 블로그

[Spring Web MVC] Thymeleaf (2)

  • 2022.08.20 14:08
  • Spring/Spring Web MVC
반응형

 

 

 

타임리프는 스프링 없이도 잘 동작하지만, 스프링과의 통합을 위한 편리한 기능들을 많이 제공한다.

 

기능을 하나하나 살펴보자.

 

 

입력 폼 처리

 

 

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

 

 

타임리프를 사용하기 전 모델을 통해 item 객체를 넘겨준다.

 

*{...} 은 선택 변수 식으로 th:object 에서 선택한 객체에 접근한다. ( ${item.itemName} 으로 작성해도 된다. )

th:field 는 폼에서 id / name / value 속성을 자동으로 만들어준다. (th:field 에서 지정한 이름으로 설정된다.)

 

 

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

 

 

HTML 폼에 체크박스가 있는 경우 전송해서 POST 방식으로 서버에게 요청하면 서버에서 요청 값을 확인 시 체크박스가 선택된 경우 해당 값이 true 로, 체크박스가 선택되지 않은 경우 해당 값이 null로 초기화 돼 있다.

 

HTML 체크박스는 선택되지 않으면 서버로 값 자체를 넘기지 않는다. 

새로 입력할 때는 그렇다 쳐도 값을 수정 시 이런 상황이 발생하면 이런 로직이 문제가 될 수 있다. 

 

스프링 MVC 는 값의 유무에 상관없이 전송될 때 무조건 함께 전송되는 히든 필드를 하나 만들어서 이런 문제를 해결한다.

 

 

<input type="checkbox" id="open" name="open" class="form-check-input">
 <input type="hidden" name="_open" value="on"/> <!-- 히든 필드 추가 -->

 

 

히든 필드의 값과 체크박스의 값을 비교해서 의도한대로 동작할 수 있도록 한다.

 

 

타임리프가 제공하는 기능을 사용하면 이 작업도 간단하게 처리할 수 있다.

 

 

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

 

(th:object 로 사용할 객체를 지정한 상태이다.)

th:field를 사용하면 체크박스의 히든 필드 관련 부분도 함께 해결해준다.

 

<input type="checkbox" id="open" class="form-check-input" name="open" value="true">
<input type="hidden" name="_open" value="on"/>

 

(렌더링 된 HTML 코드)

렌더링 시 th:field 가 히든 필드를 알아서 만들어준다.

 

 

<input type="checkbox" id="open" th:field="${item.open}" class="formcheck-input" disabled>

 

 

그리고 이렇게 th:field 와 disabled 속성을 함께 사용하면

 

<input type="checkbox" id="open" class="form-check-input" disabled name="open" value="true" checked="checked">

 

타임리프를 통해 렌더링 시 checked 속성을 만들어준다.

값이 참이면 checked를 넣어주고, 값이 거짓이면 check를 넣지 않는 방식으로 동작한다.

 

타임리프 없이 구현하려면 코드도 길어지고 지저분해진다.

타임리프가 제공하는 다양한 편의 기능을 사용해 웹 페이지를 설계하자.

 

 

하나 이상을 체크할 수 있는 멀티 체크박스를 사용해보자.

 

이 때 여러 페이지에 멀티 체크박스 관련된 데이터를 추가해야 하는데, @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;
    }

 

 

컨트롤러 내부에 있는 별도의 메서드에 적용해 해당 컨트롤러를 요청할 때 regions 에서 반환한 값이 모델에 담긴다.

 

 

        <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 를 활용해서 HTML 을 렌더링한다.

 

regions를 순회하면서 뷰를 렌더링하는데, th:for="${#ids.prev('regions')}" 를 통해 타임리프가 각각 체크박스의 아이디를 중복 없이 생성해준다. (이름은 같아도 되지만, 아이디는 달라야 한다.)

 

HTML 의 id가 타임리프에 의해 동적으로 만들어지기 때문에 ids.prev(..) ids.next(..) 처럼 id 값을 동적으로 생성한다.

 

 

 

여러 가지 선택지 중 하나만 선택해야 할 때 사용하는 라디오 버튼을 사용해보자.

 

public enum ItemType {

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

    private final String description;

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

 

 

자바의 enum을 사용해서 라디오 버튼을 구현한다.

 

 

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

 

이전과 같이 @ModelAttribute 애너테이션으로 데이터를 넘겨주자. ItemType.values() 를 사용하면 해당 enum의 모든 정보를 배열로 반환한다.

 

 

        <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>

 

 

모델을 통해 넘어간 enum을 바탕으로 HTML 을 렌더링한다.

 

라디오박스는 히든 필드를 사용하지 않는다.

체크박스는 수정 할 때 체크를 풀고 전송하면 아무 값도 넘어가지 않아서 히든 필드가 필요했는데, 라디오박스는 버튼이 선택된 상태면 수정 시에 무조건 하나를 선택해야해서 히든 필드가 필요 없다.

 

<div th:each="type : ${T(hello.itemservice.domain.item.ItemType).values()}">

 

타임리프에서는 enum을 사용할 때 모델에 값을 넘기지 않고도 위와 같이 enum을 선언해두면 enum을 사용할 수 있다.

그런데 모델을 통해 넘기는 편이 더 깔끔하니.. 이런 게 있다 정도로만 알고 넘어가자.

 

 

 

여러 선택지 중에서 하나를 선택할 때 셀렉트 박스를 사용한다. (체크박스 형식이 아님)

자바 객체를 사용해 셀렉트 박스를 사용해보자.

 

 

    @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;
    }

 

 

@ModelAttribute 애너테이션으로 자바 객체 타입의 데이터를 모델에 넘겨줬다.

 

        <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 문법으로 시작한다.

 

나머지는 체크박스 / 라디오 박스와 같다.

 

 

 

반응형
저작자표시 (새창열림)

'Spring > Spring Web MVC' 카테고리의 다른 글

[Spring Web MVC] 데이터 검증  (0) 2022.08.22
[Spring Web MVC] 메세지와 국제화  (0) 2022.08.20
[Spring Web MVC] Thymeleaf (1)  (0) 2022.08.19
[Spring Web MVC] Spring MVC와 Thymeleaf 예시  (0) 2022.08.18
[Spring Web MVC] 응답 정보 다루기  (0) 2022.08.17

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [Spring Web MVC] 데이터 검증

    [Spring Web MVC] 데이터 검증

    2022.08.22
  • [Spring Web MVC] 메세지와 국제화

    [Spring Web MVC] 메세지와 국제화

    2022.08.20
  • [Spring Web MVC] Thymeleaf (1)

    [Spring Web MVC] Thymeleaf (1)

    2022.08.19
  • [Spring Web MVC] Spring MVC와 Thymeleaf 예시

    [Spring Web MVC] Spring MVC와 Thymeleaf 예시

    2022.08.18
다른 글 더 둘러보기

정보

천천히 꾸준히 조용히 블로그의 첫 페이지로 이동

천천히 꾸준히 조용히

  • 천천히 꾸준히 조용히의 첫 페이지로 이동

검색

방문자

  • 전체 방문자
  • 오늘
  • 어제

카테고리

  • 분류 전체보기 (679)
    • Algorithm (205)
      • Data Structure (5)
      • Theory && Tip (33)
      • Baekjoon (166)
      • ALGOSPOT (1)
    • Spring (123)
      • Spring (28)
      • Spring Web MVC (20)
      • Spring Database (14)
      • Spring Boot (6)
      • Spring 3.1 (11)
      • Spring Batch (6)
      • Spring Security (16)
      • JPA (12)
      • Spring Data JPA (5)
      • QueryDSL (4)
      • eGovFramework (1)
    • Programming Language (74)
      • C (25)
      • C++ (12)
      • Java (19)
      • JavaScript (15)
      • Python (1)
      • PHP (2)
    • Computer Science (142)
      • Machine Learning (38)
      • Operating System (18)
      • Computer Network (28)
      • System Programming (22)
      • Universial Programming Lang.. (8)
      • Computer Architecture (4)
      • Compiler Design (11)
      • Computer Security (13)
    • Database (21)
      • Database (7)
      • MySQL (3)
      • Oracle (3)
      • Redis (5)
      • Elasticsearch (3)
    • DevOps (20)
      • Docker && Kubernetes (8)
      • Jenkins (4)
      • Amazon Web Service (8)
    • Mobile (28)
      • Android (21)
      • Flutter (7)
    • 💡 솔루션 (17)
    • 👥 모각코 (10)
    • 💬 기록 (8)
    • 📚 공부 (6)
    • -------------- (25)

최근 글

나의 외부 링크

메뉴

  • 홈
반응형

정보

i3months의 천천히 꾸준히 조용히

천천히 꾸준히 조용히

i3months

블로그 구독하기

  • 구독하기
  • RSS 피드

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. Copyright © i3months.

티스토리툴바