참조: http://richardbarabe.wordpress.com/2009/02/23/apache-tiles-2-integration-with-spring-mvc/
오늘은 노동자의 날(?)이라 쉬는 사람들이 많은데도 출근한 성윤군이랑 열심히 타일즈를 적용하고 있습니다. 아파치 타일즈 2 홈페이지, 프로 스프링 2.5, 스프링 3.0 레퍼런스를 보면서 적용했지만... 잘 안되더군요. 결국은 위 블로거가 제공하는 패치를 사용해서 해결했습니다.
0. pom.xml에 Tiles 라이브러리 추가하기
<!-- tiles -->
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>com.springsource.org.apache.tiles</artifactId>
<version>2.1.2.osgi</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>com.springsource.org.apache.tiles.core</artifactId>
<version>2.1.2.osgi</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>com.springsource.org.apache.tiles.servlet</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>com.springsource.org.apache.tiles.jsp</artifactId>
<version>2.1.2</version>
</dependency>
1. xxx-servlet.xml에 TilesConfigurer 추가하기 <!-- ============================================================= -->
<!-- Tiles -->
<!-- ============================================================= -->
<bean id="tilesConfigurer" class="springsprout.web.SpringTilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles/general-layout.xml</value>
<value>/WEB-INF/tiles/tiles-content.xml</value>
</list>
</property>
</bean>
2. xxx-servlet.xml에 뷰 리졸버 추가하기 <bean id="tilesViewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver"
p:viewClass="org.springframework.web.servlet.view.tiles2.TilesView" />
3. 타일즈 설정 파일 추가하기위 설정대로 /WEB-INF/ 밑에 tiles라는 폴더를 만들고 그 안에 파일 두 개를 만들어 줍니다.저희는 제일 간단한 3단 구조로 설정했습니다. general-layout.xml<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
"http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
<tiles-definitions>
<definition name=".root" template="jsp/root.jsp">
<put-attribute name="header" value="/jsp/layout/header.jsp" />
<put-attribute name="footer" value="/jsp/layout/footer.jsp" />
</definition>
</tiles-definitions>
tiles-content.xml<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
"http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
<tiles-definitions>
<definition name="index" extends=".root">
<put-attribute name="content" value="/jsp/index.jsp" />
</definition>
<definition name="login" extends=".root">
<put-attribute name="content" value="/jsp/login/login.jsp" />
</definition>
</tiles-definitions>
general-layout.xml은 그야말로 템플릿 레이아웃이고 이 레이아웃을 tiles-context.xml에 상속 받아서 사용합니다. 이렇게 해야 설정을 최소화 할 수 있겠죠. 불편한 거 하나는.. 모든 뷰를 명시적으로 저렇게 설정이 한 덩어리씩 추가가 되어야 한다는 거죠. 이걸 CoC로 어떻게 간편화 할 수 없을지 고민입니다. 타일즈에서 만들어 주세요~4. 템플릿 만들기general-layout.xml에 정의한 root.jsp, header,jsp, footer.jsp, empty.jsp 파일을 만듭니다. 이 JSP 페이지가 기본 레이아웃을 그리는 JSP 페이지입니다.roo.jsp<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>SpringSprout</title>
<link href="/css/main.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="main">
<tiles:insertAttribute name="header"/>
<tiles:insertAttribute name="content"/>
</div>
<tiles:insertAttribute name="footer"/>
</body>
</html>
header.jsp<div id="header" class="basic">
<div class="site">
<div class="logo">
<a href="/"><img src="images/logo.png" alt="springsprout" /></a>
</div>
<div class="actions">
<a href="/">Home</a>
<a href="/">Studies</a>
<a href="/">Seminars</a>
<a href="/">Blog</a>
<a href="/">Wiki</a>
<a href="/">Signup</a>
<a href="/login.do">Login</a>
</div>
</div>
</div>
footer.jsp<div id="footer">
<div class="site">
<h2>Good Bye ~~~!!</h2>
</div>
</div>
empty.jsp<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<tiles:insertAttribute name="content"/>
끝입니다. 이제 새로운 페이지를 만들 때 마다 헤더와 푸터를 제외하고 몸통 부분만 만들면 됩니다. 5. 패치1번에서 설정한 tilesConfigurer를 등록하시려면 아래 파일이 필요하실 겁니다.이 파일을 사용하지 않고 스프링이 제공하는 클래스를 사용하시면 맨 위 링크의 글에 나타나 있는 에러가 발생할 겁니다.
출처 - http://whiteship.tistory.com/2217
===================================================================================
UrlBasedViewResolver 를 이용해서 Tiles2 설정 하는 방법
- 확장자 .do 인 경우만 적용이 된다.
만약에 Tiles를 사용하지 않고 출력하는 방법을 생각할 수 있을 것이다.
order 값이 작은것을 먼저 출력한다. 하지만 같은 UrlBasedViewResolver 는 한개만 사용할 수 있는것 같다.
다른 ViewResolver 를 여러개 쓰는 것은 가능한것 같은데 프로그램 하면서 return 형태가 여러개면 헷갈리것 같다.
따라서 dummy 레이아웃을 만들던지 아니면 ROOT 폴더에 jsp 파일을 만들고 직접 jsp로 호출하는 방법이 있을것 같다.
파일명 : common-servlet.xml
1) Tiles 를 이용하지 않는 방법
<!-- Tiles 를 사용하지 않는 경우, 파일 위치 "/WEB-INF/jsp/test/vets.jsp" -->
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" p:order="1"
p:viewClass="org.springframework.web.servlet.view.JstlView"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>
2) Tiles를 이용한 방법
<!-- Tiles 사용 설정 (JSP만 사용할 경우 주석 처리 - 아래 tilesConfigurer와 같이 주석) -->
<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
<property name="order" value="0" />
</bean>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/config/tiles2def/tiles-def.xml</value>
<!-- TODO tiles definition 추가 -->
</list>
</property>
</bean>
파일명 : /WEB-INF/config/tiles2def/tiles-def.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
<definition name="home_skin" template="/WEB-INF/jsp/layouts/layout.jsp">
<put-attribute name="title" value="Guide Program" />
<put-attribute name="header" value="/WEB-INF/jsp/layouts/header.jsp" />
<put-attribute name="menu" value="/WEB-INF/jsp/layouts/menu.jsp" />
<put-attribute name="body" value="/WEB-INF/jsp/layouts/body.jsp" />
<put-attribute name="footer" value="/WEB-INF/jsp/layouts/footer.jsp" />
</definition>
<definition name="dummy" template="/WEB-INF/jsp/layouts/dummy.jsp">
<put-attribute name="title" value="Guide Program" />
<put-attribute name="body" value="/WEB-INF/jsp/layouts/body.jsp" />
</definition>
<definition name="test/vets" extends="home_skin">
<put-attribute name="title" value="테스트 제목" type="string" />
<put-attribute name="body" value="/WEB-INF/jsp/test/vets.jsp" />
</definition>
</tiles-definitions>
출처 - http://cafe.naver.com/kingja/155
===================================================================================
우선 ajax를 통해서 json 데이터를 전송시에 구현방법은
json 양식을 따르는(?) jsp를 작성하여서 client에 전송하도록 하였습니다.
따라서 SpringMVC의 controller 는 jsp파일 네임과 동일한 값을 return해야합니다.
(이를 논리적인 뷰 이름 이라고 하더군요.
/views/home.jsp 를 예로 들자면
/views/ >> 접두어
home >> 논리적인 뷰 이름
.jsp >> 접미어 라고 합니다. )
modelAndView를 사용하든, model을 사용하든 String을 이용하던 말이죠.
controller의 일이 끝나면 viewResolver에게 요청이 넘어가게 됩니다.
viewResolver는 controller 에서 넘어온 논리적인 뷰 이름과 동일한 jsp 등의 파일 등을 찾아서
data(model) 를 binding한 후에 클라이언트에게 넘겨줍니다.
그런데 tiles를 이용하여 view layer look and feel을 구성하면 TilesView 를 이용해야합니다.
모든 request는 tilesview가 적용된 resolver로 가게 되기 때문에 ajax를 이용해서 data만 가져오려던게
page를 다시 호출하게 되는 상황이 올 수 있죠.
그렇지 않더라도 tiles를 적용하면 definition 으로 각 view를 설정해주어야하는데(dynamic tiles 미적용시에)
여기에서 해당하는 view를 못찾게 되면 no mapping view라면서 404를 보게 됩니다.
(view look and feel은 spring in action 3판에서 본 용어로
application look and feel 이란 표현을 사용하더군요~)
이때 해결할 수 있는 방법은 viewResolver에 우선순위를 주어서 2개이상을 정의하는 것입니다.
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list><value>/views/**/views.xml</value></list>
</property>
</bean>
<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
</bean>
application-servlet에 정의한 xml에는 보통 위와 같이 tiles를 적용하게 될 것입니다.
이렇게 작성하면 모든 view들은 tiles가 적용되게 되죠.
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list><value>/views/**/views.xml</value></list>
</property>
</bean>
<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
<property name="order" value="1" />
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/" />
<property name="suffix" value=".jsp" />
<property name="order" value="2" />
</bean>
위와 같이 viewResolver를 적용하게되면 우선 모든 view들은 tiles를 정의한 각 views.xml의 definition들에서
binding될 jsp 등의 view 파일들을 찾게됩니다.
만약 각 views.xml에서 view 파일을 못찾게 되면 우선순위가 2인 InternalResourceViewResolver 에서
해당 view 파일을 찾게 됩니다.
filter chaining 과는 좀 다르지만 여튼 좀 비슷해보이죠??
참고로 prefix property는 접두어 suffix property는 접미어입니다 ^^;;
이를 응용하게 되면 다양한 viewResolver를 적용하여 spring에서 제공하는 여러 viewResolver들을 통해
강력한 애플리케이션을 구축할 수 있겠지요~?
출처 - http://creator1022.tistory.com/176
===================================================================================
이번 글에서는 Tiles 프레임워크와 그것을 스프링3 에 통합하는 것에 대해서 알아보겠습니다. 이전 글까지 만들었던 어플리케이션에
Tiles를 추가해 보도록 하겠습니다. 만약 소스코드가 없다면 이전글로 돌아가 소스코드를 다운받아서 진행하도록 합니다.
Tiles2 소개
요
즘 대부분의 웹사이트 들은 여러페이지에 걸쳐 재사용되는 조각들로 페이지가 나누어져 있습니다. 예를 들어서 웹 페이지의 헤더,
푸터, 메뉴 등이 그것입니다. 이것들은 웹사이트 전체에 걸쳐서 일관된 화면을 보여줍니다. 이렇게 반복되어 나타나는 페이지들을
웹사이트의 전체에 걸쳐서 하드코딩하기란 굉장히 힘든 일일 것입니다. 만약 수정사항이라도 발생하는 날엔 모든 페이지에 걸쳐 같은
수정작업을 반복해야 됩니다.
그래서 우리는 템플릿 메카니즘을 사용합니다. 일반적인 헤더, 푸터, 메뉴페이지를 하나씩 만들어놓고 각각의 페이지에서 그것을 불러오는 것입니다.
Tiles
플러그인은 바로 설명과같이 템플릿화, 컴포넌트화 하는것을 도와주는 프레임워크입니다. 사실 두 메카니즘은 매우 비슷합니다. 하나의
완성된 페이지 또는 다른 페이지의 일부를 만들기 위해 페이지의 부분들을 정의하는것입니다. ( 페이지를 조각조각 나누어
조립하는것이 "타일" 과 비슷하다고 해서 이름을 "Tiles" 라고 만든 것 같습니다.) 각각의 파트 들은 변수를 취할 수 있고,
동적인 컨텐츠를 가질 수 있으며 Java언어의 메소드로도 보여질 수 있습니다. 타일즈는 웹어플리 케이션의 모든페이지를 일관된
룩&필로 유지하기 위한 템플릿 시스템 이라고 할 수 있습니다. 이것은 코드의 중복성을 줄이고, 템플릿의 재사용성을
높여줍니다.
일반적인 웹사이트의 레이아웃은 하나의 중심이 되는 설정파일에 정의되고, 이것은 웹사이트의 모든 페이지에서 확장 될 수 있습니다.
만들려고 하는 어플리케이션의 레이아웃
우리의 목표는 이전에 만들었던 Hello world 어플리케이션에 헤더, 푸터, 메뉴를 추가하는 것입니다. 다음 그림의 형태가 될 것입니다.
필요한 JAR 파일들
스프링3 어플리케이션에 Tiles를 추가하기 위해, 몇 개의 jar 파일들이 필요합니다. 다음 리스트가 필요한 파일들입니다. 이 jar 파일들을 WEB-INF/lib 폴더에 추가해 주시기 바랍니다.
파랗게 선택된 파일들이 Tiles 추가를 위해 새로 필요한 파일들입니다.
Spring MVC 에서 Tiles 설정하기
Tiles
를 설정해주기 위해, Tiles 설정을 위한 빈을 spring-servlet.xml 에 만들어 줘야 합니다. WEB-INF폴더에
있는 spring-servlet.xml 파일을 열어서 아래 코드를 <beans> </beans> 태그
사이에 입력해 주시기 바랍니다.
File : /WebContent/WEB-INF/spring-servlet.xml
- <bean id="viewResolver"
- class="org.springframework.web.servlet.view.UrlBasedViewResolver">
- <property name="viewClass">
- <value>
- org.springframework.web.servlet.view.tiles2.TilesView
- </value>
- </property>
- </bean>
-
- <bean id="tilesConfigurer"
- class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
- <property name="definitions">
- <list>
- <value>/WEB-INF/tiles.xml</value>
- </list>
- </property>
- </bean>
<textarea style="display: none;" class="xml" name="code"><bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass">
<value>
org.springframework.web.servlet.view.tiles2.TilesView
</value>
</property>
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles.xml</value>
</list>
</property>
</bean>
</textarea>
위 설정에서 /WEB-INF/tiles.xml 이라는 파일을 빈의 변수로서
넣어주었는데, 바로 이 파일에서 웹사이트의 Tiles 에 관한 설정을 하게 될 것입니다. WEB-INF 폴더에 tiles.xml
파일을 만들고, 아래 코드를 입력해 주시기 바랍니다.
File : /WebContet/WEB-INF/tiles.xml
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE tiles-definitions PUBLIC
- "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
- "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
-
- <tiles-definitions>
-
- <definition name="base.definition"
- template="/WEB-INF/jsp/layout.jsp">
- <put-attribute name="title" value="" />
- <put-attribute name="header" value="/WEB-INF/jsp/header.jsp" />
- <put-attribute name="menu" value="/WEB-INF/jsp/menu.jsp" />
- <put-attribute name="body" value="" />
- <put-attribute name="footer" value="/WEB-INF/jsp/footer.jsp" />
- </definition>
-
- <definition name="contact" extends="base.definition">
- <put-attribute name="title" value="Contact Manager" />
- <put-attribute name="body" value="/WEB-INF/jsp/contact.jsp" />
- </definition>
-
- </tiles-definitions>
<textarea
style="display: none;" class="xml" name="code"><?xml
version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"<a
href="http://tiles.apache.org/dtds/tiles-config_2_0.dtd">http://tiles.apache.org/dtds/tiles-config_2_0.dtd</a>">
<tiles-definitions>
<definition name="base.definition"
template="/WEB-INF/jsp/layout.jsp">
<put-attribute name="title" value="" />
<put-attribute name="header" value="/WEB-INF/jsp/header.jsp" />
<put-attribute name="menu" value="/WEB-INF/jsp/menu.jsp" />
<put-attribute name="body" value="" />
<put-attribute name="footer" value="/WEB-INF/jsp/footer.jsp" />
</definition>
<definition name="contact" extends="base.definition">
<put-attribute name="title" value="Contact Manager" />
<put-attribute name="body" value="/WEB-INF/jsp/contact.jsp" />
</definition>
</tiles-definitions>
</textarea>
위의 tiles.xml 파일에 base.definition 이라는 템플릿을
정의했습니다. 이 레이아웃은 헤더, 타이틀, 바디, 메뉴, 푸터같은 것들을 포함하고 있습니다. 그리고나서 이 템플릿은 새롭게
정의한 Contact 페이지에서 확장(extend) 되고 있습니다. 기본 페이지들은 덮어쓰고, Body 와 Title에 해당하는
내용들만 바꾸어 주었습니다.
JSP 뷰 파일 만들기layout.jsp
라는 JSP파일에 템플릿 들을 정의해 줄 것입니다. 템플릿은 여러 다른 웹페이지(메뉴, 푸터, 해더 등) 조각들로 구성됩니다.
layout.jsp, menu.jsp, header.jsp, footer.jsp 이렇게 4개의 JSP 파일들을 만들고 아래의
코드를 입력해 주시기 바랍니다.
File: /WebContent/WEB-INF/jsp/layout.jsp
- <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title><tiles:insertAttribute name="title" ignore="true" /></title>
- </head>
- <body>
- <table border="1" cellpadding="2" cellspacing="2" align="center">
- <tr>
- <td height="30" colspan="2"><tiles:insertAttribute name="header" />
- </td>
- </tr>
- <tr>
- <td height="250"><tiles:insertAttribute name="menu" /></td>
- <td width="350"><tiles:insertAttribute name="body" /></td>
- </tr>
- <tr>
- <td height="30" colspan="2"><tiles:insertAttribute name="footer" />
- </td>
- </tr>
- </table>
- </body>
- </html>
<textarea
style="display: none;" class="html" name="code"><%@ taglib
uri="<a
href="http://tiles.apache.org/tags-tiles">http://tiles.apache.org/tags-tiles</a>"
prefix="tiles"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<a
href="http://www.w3.org/TR/html4/loose.dtd">http://www.w3.org/TR/html4/loose.dtd</a>">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8">
<title><tiles:insertAttribute name="title" ignore="true"
/></title>
</head>
<body>
<table border="1" cellpadding="2" cellspacing="2" align="center">
<tr>
<td height="30" colspan="2"><tiles:insertAttribute
name="header" />
</td>
</tr>
<tr>
<td height="250"><tiles:insertAttribute name="menu"
/></td>
<td width="350"><tiles:insertAttribute name="body"
/></td>
</tr>
<tr>
<td height="30" colspan="2"><tiles:insertAttribute
name="footer" />
</td>
</tr>
</table>
</body>
</html>
</textarea>
File : /WebContent/WEB-INF/jsp/header.jsp
<textarea style="display: none;" class="html" name="code"><h1>Header</h1>
</textarea>
File : /WebContent/WEB-INF/jsp/menu.jsp
<textarea style="display: none;" class="html" name="code"><p>Menu</p>
</textarea>
File : /WebContent/WEB-INF/jsp/footer.jsp
- <p>Copyright © ViralPatel.net</p>
<textarea style="display: none;" class="html" name="code"><p>Copyright © ViralPatel.net</p>
</textarea>
준비 끝!
이클립스에서 컴파일하고 어플리케이션을 실행시켜서, 헤더, 메뉴, 푸터가 제대로 들어가 있는지 확인한다.
소스코드 다운로드
출처 - http://blog.naver.com/PostView.nhn?blogId=darkleepb&logNo=100154737506