
본 글은 김영한님의 인프런 강의를 참조합니다
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
ref : https://programmer93.tistory.com/40
개념
스프링에서 권장하는템플릿 엔진
HTML파일을 가져와서파싱하고분석한 후,정해진 위치에데이터를 치환해서 웹 페이지를 생성
JSP vs Thymeleaf
- JSP
템플릿 엔진이X-->HTML내에Java코드를삽입해서동적 페이지를 생성하는서버사이드 스크립트 언어
Java Servlet으로 변환되어 실행O
배포를 위해 WAR(Web Application Archive) 타입이 사용 (JAR에 비해 무거움)
HTML파일 미리보기시코드와 함께 존재하므로 정상 결과X
- Thymeleaf
템플릿 엔진O
Java Servlet으로 변환되어 실행X
배포를 위해 JAR(Java Archive) 타입 사용
HTML파일 미리보기시 정상 결과O
추가
- 템플릿 엔진 ?
HTML과데이터를결합해서결과물을 만들어 주는 도구- ex)
Thymeleaf/Velocity/Mustach등
- SpringBoot 경로
- 정적 파일 :
/resources/static- 동적 파일(
템플릿 엔진등) :/resources/templates
WARvsJAR
- WAR(
Web application ARchive)
Servlet / JSP 컨테이너에 배치할 수 있는웹 어플리케이션(Web Application)압축 파일 포맷
Servlet 해석과 관련된모든 패키지들을 포함해서무거운 구조를 가짐
단독으로 실행 불가하며WEB / WAS가 함께수행되어야 함- JAR(
Java ARchive)
쉽게 Java 어플리케이션이 동작할 수 있도록Java 프로젝트를 압축한 파일- JDK(
Java Development Kit)에 있는 JRE(Java Runtime Environment)만 있으면실행 가능
Java만 설치되면 실행 가능
- 핵심
th:xxx가 붙은 부분은서버 사이드에서 렌더링되고,기존 속성을 대체하는 원리
서버에서 동적으로 데이터를 변경할 때th:xxx로속성을 대체하는 것
HTML파일을 직접 열었을 때, 브라우저는th: 속성을 모르니까무시하고 출력됨
- 선언
<html xmlns:th="http://www.thymeleaf.org">
- URL 링크 표현식
- 타임리프에서
URL링크를 사용하는 경우@{...}를 사용한다
Path Variable뿐만 아니라Query Parameter도 생성해서 사용할 수 있다/* 기본 사용 */ <a th:href="@{/css/bootstrap.min.css}"/> /* Path Variable / Query Parameter */ <a th:href="@{/basic/items/{itemId}(itemId=${item.id}, query='test')}" /> 실제 생성 링크 예시 --> http://localhost:8080/basic/items/1?query=test
- 속성 변경
타임리프의 핵심이 바로기존 속성을동적으로 대체할 수 있게속성을 변경하는 것- 아래 예시는
onclick시특정 경로로 이동하게 동적으로 처리<button onclick="location.href='addForm.html'" th:onclick="|location.href='@{/basic/items/add}'|" />
- 리터럴 대체
- 타임리프에서
문자와표현식등은분리되어 있기 때문에,더해서 사용해야 한다- 하지만,
가독성과사용성이 떨어지므로|...|를 통해리터럴을 대체할 수 있다/* 기존 방법 */ <button onclick="location.href='addForm.html'" th:onclick="location.href=' + '/'' + @{/basic/items/add} + '\'" /> /* 리터럴 대체 사용 */ <button onclick="location.href='addForm.html'" th:onclick="|location.href='@{/basic/items/add}'|" />
- 반복 출력
th:each를 사용해서model에 포함된 값을반복적으로 순회하며수행할 수 있다<tr th:each="item : ${items}"> <td><a href="item.html" th:href="@{/basic/items/{itemId}(itemId=${item.id})}">회원id</a></td> <td><a href="item.html" th:href="@{|/basic/items/${item.id}|}"th:text="${item.itemName}">상품명</a></td> </tr>
- 내용 변경
text 속성 값을 특정 값으로대체/* 정적인 경우의 10000을 가지지만, 값이 넘어오면 item.price로 대체 */ <td th:text=${item.price}">10000</td>
- PRG 패턴
- PRG 패턴은 웹 개발시 자주 사용되는
디자인 패턴
POST 요청에 대한 응답이또 다른 URL로의 GET 요청을 위한리다이렉트(응답 코드가 3XX)여야 한다는 것- 만약
POST요청에 대한 응답이 리다이렉트가 아닌단순 페이지 이동이면문제가 발생함
- 문제점(
POST 응답이단순 페이지 이동인경우)
브라우저 새로고침을 할 때 마다POST요청이 수행된다 -->중복 수행- 따라서 반드시
PRG 패턴을 적용해야 함
Redirect를 이용해서GET을 호출하도록 설계- 이제
브라우저 새로고침이 있어도 해당되는GET만 다시 요청됨
Post 요청 후 redirect 수행시주의사항
특정 값을 추가해서redirect할 때,해당 값은인코딩 과정이 수행되지 않는다
-->한글인 경우 모두 깨지게 됨
-->이것을 해결하기 위해RedirectAttributes를 사용할 수 있음@PostMapping("/add") public String addItemV5(Item item) { itemRepository.save(item); /* Path Variable로 추가되는 item의 id와 같은 변수를 추가적으로 인코딩 되지 않음 */ return "redirect:/basic/items/" + item.getId(); }
Redirect를 할 때URL 인코딩,Path Variable/Query Parameter를처리해주는도구
특정 View에서Redirect의 여부를 확인하기 위해변수를 전달하기 위해 사용하기도 함
@PostMapping("/add") public String addItemV6(Item item, RedirectAttributes redirectAttributes) { Item savedItem = itemRepository.save(item); redirectAttributes.addAttribute("itemId", savedItem.getId()); redirectAttributes.addAttribute("status", true); return "redirect:/basic/items/{itemId}"; }
RedirectAttributes객체 사용
.addAttribute로값을 추가할 수 있음
url 경로에변수가 존재하면 넣어주며, 없으면자동으로 Query Parameter로처리됨- 실제 요청 예시 :
http:localhost:8080/basic/items/3?status=true