참고
https://insight-bgh.tistory.com/252
템플릿 엔진이란?
템플릿 엔진이란 동적 컨텐츠를 생성하는 방법이다.
템플릿 양식과 특정 데이터 모델에 따른 입력 자료를 결합하여 결과 문서를 출력하는 소프트웨어를 말하며 view code(html)과 data logic code(db connection)을 분리해주는 기능을 한다.
스프링 MVC에서 주로 동적인 View를 만드는데 사용한다. 그렇다고 View만 만드는데 사용하지는 않으며 이메일 등 다양한 용도로 사용 가능하다.
템플릿 엔진에는 서버사이드, 클라이언트 사이드 두 가지가 있다.
- 서버 사이드 템플릿 엔진 : 서버에서 가져온 데이터를 미리 정의된 템플릿에 넣어 html을 그린 뒤 클라이언트에게 전달해준다.
- HTML 코드에서 고정적으로 사용되는 부분은 템플릿으로 만들어두고, 동적으로 생성되는 부분만 템플릿에 소스코드를 끼워넣는 방식으로 동작한다.
- 클라이언트 사이드 템플릿 엔진 : HTML 형태로 코드를 작성하며, 동적으로 DOM을 그리게 해주는 역할을 한다.
- 데이터를 받아서 DOM 객체에 동적으로 그려주는 프로세스를 담당한다.
스프링 부트가 자동 설정을 지원하는 템플릿 엔진
- FreeMarker
- Groovy
- Thymeleaf
- Mustache
Thymeleaf와 달리 JSP는 스프링부트가 자동 설정을 지원하지 않으며 권장하지도 않는다.
왜 Spring Boot에서는 JSP를 권장하지 않을까?
우선 JSP를 사용하면 JAR 패키징을 할 수 없어 WAR 패키징을 해야한다. 물론, WAR패키징으로도 임베디드 톰캣으로 실행할 수 있고 배포도 가능하다.
하지만 Undertow라는 최근에 만들어진 서블릿 엔진이 JSP를 지원하지 않는 등 제약사항이 있다.
또한 JSP에 대한 의존성을 넣으면 의존성 문제가 생기는 경우도 있다.
JAR와 WAR 모두 JAVA의 jar
툴을 이용해 생성된 파일이며 애플리케이션을 쉽게 배포하고 동작시킬 수 있도록 관련 파일을 패키징해준다.
.jar
자바 프로젝트를 압축한 파일.war
servlet / jsp 컨테이너에 배치할 수 있는 웹어플리케이션 압축 파일java -jar
)을 이용해 생성하는 JAR 파일의 일종이다. Thymeleaf는 비교적 최근에 만들어진 템플릿 엔진이며 서버사이드 자바 템플릿 엔진의 한 종류이다.
JSP와 Thymeleaf의 가장 큰 차이점은 JSP와 달리 Servlet Code로 변환되지 않다는 점이다. 따라서 비즈니스 로직과 분리되어 오로지 View에 집중할 수 있다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
기본적으로 모든 View는 src
- templates
디렉토리에 있다.
@Controller
public class SampleController {
@GetMapping("/hello")
public String hello(Model model) {
model.addAttribute("name", "dsunni");
return "hello";
}
}
@Controller
이기 때문에 return하는 String은 View의 이름이된다.template
- hello.html)<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>
@RunWith(SpringRunner.class)
@WebMvcTest(SampleController.class)
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void hello() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/hello"))
.andExpect(status().isOk())
.andDo(print())
.andExpect(view().name("hello"))
.andExpect(model().attribute("name", is("dsunni")));
}
}
MockHttpServletRequest:
HTTP Method = GET
Request URI = /hello
Parameters = {}
Headers = {}
Body = <no character encoding set>
Session Attrs = {}
Handler:
Type = me.dsunni.SampleController
Method = public java.lang.String me.dsunni.SampleController.hello(org.springframework.ui.Model)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = hello
View = null
Attribute = name
value = dsunni
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">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>
Forwarded URL = null
Redirected URL = null
Cookies = []
.andDo(print())
를 통해 렌더링 된 결과까지 확인할 수 있는데, 이것은 Thymeleaf를 사용했기 때문이다.
JSP를 사용하면 본문을 확인(렌더링된 결과)하는 것이 매우 힘들다.
서블릿 엔진 자체가 JSP 템플릿을 완성시키기 때문에 응답으로 내보낼 최종적인 View를 확인하기 위해서는 서블릿 엔진 개입이 필수적이다.
반면 Thymeleaf는 서블릿 컨테이너의 개입 없이 독자적으로 최종적인 View를 완성한다.
테스트에서 사용한 mockMVC는 가짜 서블릿 컨테이너이며 실제 서블릿 컨테이너가 할 수 있는 일을 다 할 수 없다. 따라서 만약 JSP였더라면 렌더링된 결과를 확인할 수 없없을 것이다.
https://www.thymeleaf.org/doc/articles/standarddialect5minutes.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 th:text="${name}">Name</h1>
</body>
</html>
Thymeleaf 사용하기 위해 th
네임스페이스 추가
Controller에서 Model로 받아온 name
사용
<h1 th:text="${name}">Name</h1>
Controller에서 내려준 name attribute값이 잘 전달되었다