부트 개념과 활용-18.Thymeleaf


스프링 웹 MVC 7부: Thymeleaf

스프링 부트가 자동 설정을 지원하는 템플릿 엔진

  • FreeMarker
  • Groovy
  • Thymeleaf
  • Mustache

JSP는 없다.(자동설정 미지원, 권장하지도 않는다.)

JSP를 권장하지 않는 이유

  • 스프링 부트는 임베디드 톰캣으로 애플리케이션을 빠르고 쉽게 만들어 배포하길 원한다.

  • JAR 패키징 할 때는 동작하지 않고, WAR 패키징 해야 함. (물론 war로 패키징 하더라도 실행은 가능하다.)

  • Undertow는 JSP를 지원하지 않음.

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-jsp-limitations

Thymeleaf 사용하기

https://www.thymeleaf.org/
https://www.thymeleaf.org/doc/articles/standarddialect5minutes.html

의존성 추가: spring-boot-starter-thymeleaf
템플릿 파일 위치: /src/main/resources/template/
예제: https://github.com/thymeleaf/thymeleafexamples-stsm/blob/3.0-master/src/main/webapp/WEB-INF/templates/seedstartermng.html

예제코드

@ExtendWith(SpringExtension.class) // junit 5 기준
@WebMvcTest(SampleController.class)
class SampleControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Test
    public void hello() throws Exception {

        // 요청 "hello"
        // 응답
        // - 모델 name : jaeuk
        // - 뷰 이름 : hello

        mockMvc.perform(get("/hello"))
                .andExpect(status().isOk())
                .andDo(print()) // 렌더링된 결과를 확인 가능
                .andExpect(view().name("hello"))
                .andExpect(model().attribute("name", "jaeuk")); // junit 5 기준
    }
}
@Controller
public class SampleController {

    @GetMapping("/hello")
    public String hello(Model model){
        model.addAttribute("name", "jaeuk");

        return "hello"; // hello view name 리턴
    }
}

templete -> hello.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<!-- 타임리프 사용하려면 html 문서에 선언 xmlns:th="http://www.thymeleaf.org" -->
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1 th:text="${name}"> null name jaeuk </h1>
<!-- name 값 전달되면 전달된 값 없으면 null name jaeuk -->
</body>
</html>

출력결과

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /hello
       Parameters = {}
          Headers = []
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = me.jaeuk.thymeleaf.SampleController
           Method = me.jaeuk.thymeleaf.SampleController#hello(Model)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = hello
             View = null
        Attribute = name
            value = jaeuk

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Language:"en", Content-Type:"text/html;charset=UTF-8"]
     Content type = text/html;charset=UTF-8
             Body = <!DOCTYPE html>
<html lang="en">
<!-- 타임리프 사용하려면 html 문서에 선언 xmlns:th="http://www.thymeleaf.org" -->
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>jaeuk</h1>
<!-- name 값 전달되면 전달된 값 없으면 null name jaeuk -->
</body>
</html>
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

andDo.(print()) 렌더링된 결과를 확인 가능 타임리프를 쓰니까 가능한 것.

JSP를 사용할 땐 렌더링 한 결과를 확인하기 힘들다.

서블릿 엔진이 개입을 해야만(서블릿 엔진이 만들어 내야만..) 응답을 내보낼 최종적인 뷰를 확인할 수 있다.

근데 타임리프는 독자적으로 최정적인 뷰를 완성한다.

서블릿 컨테이너의 개입 없이,
WebMvcTest는 서블릿 컨테이너를 띄우는게 아니다. (가짜 서블릿 컨테이너) - 서블릿 컨테이너의 역할 못 함 즉, JSP를 렌더링 시켜서 확인 못한다.

하지만 타임리프는 서블릿 컨테이너에 독립적인 엔진이라 뷰에 렌더링되는 결과까지도 확인이 가능.

출력 결과 jaeuk 확인.

더 자세한 내용은 위의 타임리프 문서 참조.




© 2019. by jaeuk