이번 포스팅에서는 View에 대한 이해와 설정, Tiles 설정에 대해 알아보도록 하겠습니다.
우선, 포스팅에 앞서 View가 어떤 역할을 하는지 설명하기 위해 앞선 포스팅 내용 일부를 발췌하였습니다.
View의 역할
Spring MVC의 요청 처리과정에서
DispatcherServlet
이 응답 결과(View)를 반환하는 과정입니다.
Controller
는View
또는ModelAndView
객체를DispatcherServlet
에게 반환합니다.DispatcherServlet
은Controller
에게 받은 값을ViewResolver
에게 전달하여, *ViewResolver
는prefix
와suffix
를 적용한 값을 다시DispatcherServlet
에게 반환합니다.DispatcherServlet
은 해당 뷰를 호출하면서 Model도 함께 전달합니다.View
은Model
객체를 가져와서 응답결과를 만들고 클라이언트에게 응답 결과를 전달합니다.
- 이 때,
Model
값은 없을 수도 있습니다.
Spring MVC의 요청처리 과정을 살펴보면 ViewResolver
의 역할은 DispatcherServlet
이 View를 객체를 찾는 역할을 합니다.
우리가 처음 애플리케이션을 실행했을 때 아래와 같은 페이지를 볼수 있습니다.
HomeController
에서 /
로 요청이 들어올 시, home
이라는 View
를 반환합니다. 그리고, 이는 DispatcherServlet
에게 home
이라는 값이 전달됩니다.@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = df.format(date);
model.addAttribute("serverTime", formattedDate);
return "home";
}
}
DispatcherServlet
은 이것을 실제로 수행할 View
를 찾기 위해 ViewResolver
에게 요청합니다.ServletContext
인 context-servlet.xml
에 기술된 대로, InternalResourceViewResolver
에게 요청합니다.<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
/WEB-INF/views/home.jsp
를 반환합니다.결론적으로 이야기하면
prefix
와 suffix
를 붙여 View를 반환하는 Resolver를 변경하기 위해서는 ViewResolver를 바꿀 Resolver를 넣어줘야 합니다.tiles
란 Apache
에서 제공하는 오픈소스 템플릿 프레임워크입니다.
타일즈를 사용하면 아래와 같이 Header
, Sidebar
, Body
등 페이지 조각(타일, component
)을 정의하여, 이러한 타일을 다른 타일에 포함하여 일련의 재사용 가능한 템플릿(template
)을 개발할 수 있습니다.
이렇게 개발된 템플릿을 설정에 따라 View
에 적용할 수 있습니다.
Tiles를 사용하기에 앞서 라이브러리를 다운 받습니다. pom.xml
에서 tiles 관련 라이브러리를 세팅해줍니다.
<properties>
<org.tiles-version>3.0.8</org.tiles-version>
</properties>
<!-- Tiles -->
<dependencies>
...
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>${org.tiles-version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>${org.tiles-version}</version>
</dependency>
</dependencies>
context-servlet.xml
에 TilesViewResolver
를 추가하고, 기존 ViewResolver
의 우선순위를 낮춥니다.
(기존 ViewResolver
는 삭제해도 되지만, 우선순위를 낮춘 이유는 tiles에 매핑되지 않으면 다른 resolver를 사용하도록 사용한 것입니다.)
<!-- Tiles View Resolver -->
<beans:bean id="tielsViewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver">
<beans:property name="order" value="1" />
</beans:bean>
<!-- Tiles Configurer -->
<beans:bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<beans:property name="definitions">
<beans:list>
<beans:value>classpath:tiles/tiles.xml</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<!-- JSP View Resolver -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
<beans:property name="order" value="2" />
</beans:bean>
Tiles Configurer
은 tiles
의 설정을 관리하는 곳입니다.
해당 경로 classpath:tiles/tiles.xml
에 파일을 생성하고, 아래와 같이 넣습니다.
Tiles
의 문서 타입 정의(DTD)
가 설정되어있기 때문에 [Ctrl
+ Space바
]로 엘리멘트 태그를 찾을 수 있습니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<definition>
...
</definition>
</tiles-definitions>
Tiles의 모든 설정(template
설정, component
추가, binding
추가) 등이 해당 파일에서 이루어집니다.
Tiles의 구성 요소는 크게 template
, component
, layout
로 나눌수 있습니다. template
는 component
를 조합한 것이며, layout
페이지를 통해 웹 구성 페이지(jsp)로 만들수 있습니다.
<!-- Default Layouts -->
<definition name="default" template="/WEB-INF/tiles/layouts/default.jsp">
<put-attribute name="include" value="/WEB-INF/tiles/components/include.jsp"/>
<put-attribute name="config" value="/WEB-INF/tiles/components/config.jsp"/>
</definition>
template 설정은 definition에 template에 적용할 layout을 설정하면 됩니다.
default
레이아웃으로 설정된 default.jsp
페이지에서는 위에서 선언한 attribute
를 사용하여 페이지를 구성할 수 있습니다.
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles"%>
<!DOCTYPE html>
<html>
<head>
<tiles:insertAttribute name="include" />
<link rel="stylesheet" href="/resources/css/tiles/default.css">
</head>
<body>
<tiles:insertAttribute name="content" />
</body>
</html>
보통 페이지가 많아질 수록 url
바인딩을 모두 직접하지 않고, @PathVariable
을 통해 일정 url 타입을 바인딩하는데, tiles에서도 와일드 카드(*)
를 이용해 이와 같이 설정할 수 있습니다.
<!-- 직접 바인딩 -->
<definition name="main" extends="default">
<put-attribute name="content" value="/WEB-INF/views/home.jsp" />
</definition>
<!-- 간접 바인딩 -->
<definition name="*" extends="default">
<put-attribute name="content" value="/WEB-INF/views/{1}.jsp" />
</definition>
jsp에서 layout을 설정하기 위해서는 jsp tiles 태그 라이브러리를 세팅해야 합니다. 마찬가지로 [Ctrl
+ Space
]를 통해서 태그 라이브러리의 태그 엘리멘트들을 볼수 있습니다.
layout 페이지에서는 앞선 template 설정에서 추가했던 Attribute(component)들만 넣을 수 있습니다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles"%>
<!DOCTYPE html>
<html>
<head>
<tiles:insertAttribute name="include" />
<link rel="stylesheet" href="/resources/css/tiles/template.css">
</head>
<body>
<tiles:insertAttribute name="config" />
<tiles:insertAttribute name="side" />
<div class="header">
<tiles:insertAttribute name="header" />
</div>
<div class="content">
<tiles:insertAttribute name="content" />
</div>
<div class="footer">
<tiles:insertAttribute name="footer" />
</div>
</body>
</html>
이번 포스팅에서는 Tiles 세팅에 대해 알아보았습니다.
세팅하는 포스팅을 작성하기는 했지만 안타깝게도 Tiles는 버전 3.0.8
을 마지막으로 2016년도 이래로 지원이 끝났기 때문에 굉장히 레거시한 기술이라고 볼수 있습니다. 때문에 새로운 템플릿 엔진을 고려하는 것도 중요합니다.