[6] 스프링 MVC (13) - 타임리프 / PRG 패턴 / RedirectAttributes

김정욱·2021년 6월 10일
0

[6] 스프링 MVC

목록 보기
13/13
post-thumbnail

본 글은 김영한님의 인프런 강의를 참조합니다
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard

타임리프(Thymeleaf)

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
  • WAR vs JAR
    • 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(Post-Redirect-Get) 패턴

[ 개요 ]

  • PRG 패턴
    • PRG 패턴은 웹 개발시 자주 사용되는 디자인 패턴
    • POST 요청에 대한 응답또 다른 URL로의 GET 요청을 위한 리다이렉트(응답 코드가 3XX)여야 한다는 것
    • 만약 POST요청에 대한 응답이 리다이렉트가 아닌 단순 페이지 이동이면 문제가 발생함
  • 문제점(POST 응답단순 페이지 이동인경우)
    • 브라우저 새로고침을 할 때 마다 POST요청이 수행된다 --> 중복 수행
    • 따라서 반드시 PRG 패턴을 적용해야 함

[ 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();
}

RedirectAttributes

[ 개념 ]

  • 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
profile
Developer & PhotoGrapher

0개의 댓글