Site Search :
Standard Enterprise XML Methodology Pattern Setting Tunning Other
Article Contributors
GuestBook
Javapattern Maven
XSourceGen Dev
JetSpeed Test
JLook Image
jLook Family Site


Struts 1.1 Tiles-framework에 대한 개요 및 사용방법
 
이번 아티클은 Jakarta-Struts에 1.1부터 component로 정식포함 Tiles-Framework을 이용하여 Struts을 이용한 template에 대한 설명을 하고자 한다.
만약 당신이 struts를 1.0버젼때부터 사용해봤다면 tiles가 얼마나 강력한 화면 구성도구인지 이미 알고 있을 것이며, 몰라도 새로 배우면 되므로 아무런 상관이 없음을 밝힘다. ^^ ( 2003/07/14 ) 592
Written by ienvyou - 최지웅
1 of 1
 

이번 아티클은 Jakarta-Struts에 1.1부터 component로 정식포함 Tiles-Framework을 이용하여
Struts을 이용한 template에 대한 설명을 하고자 한다.

만약 당신이 struts를 1.0버젼때부터 사용해봤다면 tiles가 얼마나 강력한 화면 구성도구인지
이미 알고 있을 것이며, 몰라도 새로 배우면 되므로 아무런 상관이 없음을 밝힘다. ^^

▶ About Tiles

사실 기존의 Tiles가 없을때는 struts에서 화면을 구성하는 템플릿에서 org.apache.struts.taglib.template을
이용한 put tag를 이용하여 화면을 조립하였었는데 문제는 화면에 대한 구성을 자유자재로
하지 못하는다는 것을 javapattern.info사이트 구축시에 이미 느꼈었다. 이미 연재한 
Mini-Spider Framework에서는 화면구성에 대한 템플릿을 조합하는 serlvet component를 두어서
xml에서 읽어들인 데이터로 layout.jsp를 구성한 다음 뿌려주게끔 만들었었는데 그 부족한 부분을
struts에 채워줬던 것이 바로 tiles-framework이다.

이것은 2002년 1월에 아주 똑똑한 apache-contributor인 Cedric Dumoulin란 사람이 컴포넌트 형대로
처음 소개했고, 2002년 2월에 tomcat에서 tag로 사용되던 것을 struts 1.1버젼의 개발 릴리즈에
포함시키기로 결정되었었다.
현재는 struts API를 봤을때 org.apache.struts.tiles 및 org.apache.struts.tiles.taglib 패키지로
요약되어 지고 있다.

대략 tiles가 가진 기능을 살펴보면 다음과 같다.

  1. 우선 tiles에 대한 식별을 한후 그것을 기술하고 당신의 화면형태로 조립하여 사용할수 있다.
  2. 이미 기술된 레이아웃에 대하여 재사용 및 템플릿을 관리할 수 있다.
  3. 화면단에 대한 tiles의 선언 및 정의를 할 수 있으며, 파라미터 값을 통하여 struts에서 넘어온 값을 변경시킬 수 있다.
  4. 새로운 레이아웃 생성 및 객체지향의 상속개념을 통하여 불필요한 선언을 필요없게 만든다.
  5. 국제화에 대한 tiles를 생성하여 처리할 수 있다.
Tiles 설정 기본의 Struts1.0을 이용하게 된다면 tiles에 대한 jar파일을 apache foundation에서 다운로드 받아 당연히 WEB-INF의 lib에 복사하여 사용하게 되는데 더 필요한 것을 taglib에 관련한 설정을 이용하여 처리해야 하므로 web.xml에 대하여 uri정보를 설정하던지 아니면 만들어질 페이지에 대하여 적절한 설정을 해주어야 함은 물론이며, 이글을 읽는 당신~! 당연히 할줄 알고 있으리라 놀새는 믿는다. ▶ 첫번째 기본 레이아웃에 대한 설정 우선 가장 기본적으로 우리가 많이 볼수 있는 샘플 화면에 대하여 살펴보도록 하자. 프레임을 좋아하는 사람도 있겠지만 놀새~ 스스로는 single frame안에 layout을 나누어 해당 jsp만 include를 하는 것을 선호하고 있다. 그렇게 하는 게 훨씬 핸들링하기 쉽다고 생각하는데 뭐 개인마다 취향이 틀리므로 아무렇게나 사용하고 싶은데로 쓰면 되겠다. 우선 아래와 같은 형태의 화면 레이아웃이 나왔다고 가정을 하자.
header
menu body
footer
java.sun.com에서 샘플로 보여주는 petstore에서는 위와 같은 형태를 조합하는 웹페이지조립용 servlet component를 두어 layout으로 설정된 페이지로 무조건 forwarding시키면 거기서 데이터를 로딩된 xml정보를 이용하여 각 영역에 들어가야 할 페이지에 대한 부분을 include시키는 형태를 취하고 있다. 위에서 이야기하는 보통의 header에는 기업의 로고 또는 대분류메뉴들이 들어가게 되며, 거의 바뀌지 않는 내용이 대부분이며, 왼쪽편의 menu파트, 아래쪽의 footer(보통 copyright) 또한 바뀌지 않는 부분이라구 생각해도 된다. 페이지를 조립하는 데 있어서 한가지 주의해야 할 점은 링크부분에 관련한 설정인데 만약 struts의 taglib를 사용하게 되지 않는다면 이미지등의 경로를 입력하는 데 있어서 <img src='<%= request.getContextPath() %>/images/xxx.gif>의 형태로 처리해야 하며 struts taglib를 사용하면 <html:img src="/images/xxx.gif" />의 형태로 만들어줘야 한다. 사실 위의 layout에서 가장 많이 변동되는 부분은 당연히 body부분이 될 것이다. 자 그러면 이제부터 본격적인 tiles의 configure를 작성해보도록 하자. ▶ Page안에서의 Tiles조립 우선 struts에서 화면을 조립할 수 있는 2가지방법이 있다고 위에서 말했는데 template패키지를 이용한 화면조립이 그 첫번째이고 tiles를 이용한 방법이 두번째라고 말했다. - Tiles선언
<%@taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %> <tiles:insert page="/basic/myLayout.jsp" flush="true"> <tiles:put name="title"value="My first page" /> <tiles:put name="header" value="/tutorial/common/header.jsp" /> <tiles:put name="footer" value="/tutorial/common/footer.jsp" /> <tiles:put name="menu" value="/tutorial/basic/menu.jsp" /> <tiles:put name="body" value="/tutorial/basic/helloBody.jsp" /> span lang=EN-US></tiles:insert>
- Strus template pacakage선언
<%@taglib uri="/WEB-INF/tiles.tld" prefix="template" %> <template:insert page="/basic/myLayout.jsp" flush="true"> <template:put name="title"value="My first page" /> <template:put name="header" value="/tutorial/common/header.jsp"/> <template:put name="footer" value="/tutorial/common/footer.jsp"/> <template:put name="menu" value="/tutorial/basic/menu.jsp"/> <template:put name="body" value="/tutorial/basic/helloBody.jsp"/> </template:insert>
위의 코드에서 보여주는 것은 tiles.tld를 선언하여 put에 대한 tag를 만났을 경우 name에 해당하는 layout페이지의 각 영역에 value값들이 "/tutorial/common/header.jsp"의 형태로 삽입되도록 선언한 것이다. 그렇다면 이제 main layout에 관련한 화면구성의 html template를 먼저 작성해보도록 하자. 이것은 웹디자이너와도 상의를 하여야 할 것이며, 전체 프로젝트에서 화면에 대한 프로토타이핑이 이루어진 시점에서 구성이 되어도 무방할 것이다.

<table border='1' width='300'>
<tr>
    <td colspan='2' bgcolor='#CCFFFF'>header
    </td>
</tr>
<tr height='200'>
    <td width='60' bgcolor='yellow'>menu
    </td>
    <td bgcolor='#CCFF66'>body</td>
</tr>
<tr>
    <td colspan='2' bgcolor='#CCFFFF'>footer
    </td>
</tr>
</table>
위의 html형태와 이미 본 그림처럼 설정을 했었는데 위의 각 영역에 붙일 수 있는 tiles를 선언해 보도록 하자. 우선 아래와 같이 tiles taglib를 사용할 수 있도록 먼저 prefix에 대한 선언을 한후 <%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %> 아래와 같이 각각의 영역에 들어갈 attribute들에 대한 선언을 하도록 한다. <tiles:insert attribute=”body” flush=”true” /> 최종적으로 taglib가 포함되어 변경된 html source를 보게 되면

<TABLE width="100%">
  <TR>
    <TD colspan="2"><tiles:insert attribute="header" /></TD></TR>
  <TR>
    <TD width="120"><tiles:insert attribute="menu" /></TD>
    <TD><tiles:insert attribute="body" /></TD></TR>
  <TR>
    <TD colspan="2"><tiles:insert attribute="footer" /></TD>
  </TR>
</TABLE>
위와 같이 선언된다면 각각의 영역에 그 대표 이름을 붙임으로서 tiles:insert에 대한 tag library가 호출되면 해당 클래스가 config에서 이미 설정된 value를 이용하여 포함된 jsp파일을 각 영역에 include시키는 방법을 사용하고 있다. 화면 조립에 대한 이러한 기본 아키텍쳐가 궁금하다면 먼저 아래의 아티클을 읽은 후 다시 보면 되겠다. Web Application Framework개발방법(3)-View page ComposingPage안에서의 html page title 세팅 브라우져의 타이틀바에 보여져야 할 내용도 동적으로 변경을 가할 수 있는데 이것 또한 tiles가 제공하는 title tag를 이용하여 처리하면 config에 설정된 내용을 동적으로 가져 올수 있는 특징을 가지고 있다.

<head>
    <title><tiles:getAsString name="title"/></title>
</head>
최종 페이지 구성 위와 같이 구성되어 완성된 템플릿 페이지는 아래와 같다.

<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>
<html>
<head>
    <title><tiles:getAsString name="title"/></title>
</head>
<body>
<TABLE width="100%">
  <TR>
    <TD colspan="2"><tiles:insert attribute="header" /></TD></TR>
  <TR>
    <TD width="120"><tiles:insert attribute="menu" /></TD>
    <TD><tiles:insert attribute="body" /></TD></TR>
  <TR>
    <TD colspan="2"><tiles:insert attribute="footer" /></TD>
  </TR>
</TABLE>
</body>
</html>
자, 이제 화면을 구성할 수 있는 layout페이지가 조립이 되었다. 위의 페이지의 이름을 "/layout/classicLayout.jsp"라고 정하자. 이제 그곳에 내용을 입력할 수 있는 두가지 방법이 존재하게 되는데 그 두가지 방법 모두를 한번 살펴보도록 하자. ▶ 가장 기본적인 template삽입방법 우선은 layout페이지가 정의되었을 때 그 페이지의 실제 보여지게 각각의 페이지가 어떤것인지를 알려주어 삽입하도록 하게 하는 방법이다. 위에서 템플릿 파일의 이름을 classicLayout.jsp라고 정의했고, 아래의 파일이름은 실제 최초요청이 들어왔다는 가정으로 index.jsp라고 하자.

<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>
<tiles:insert page="/layout/classicLayout.jsp" flush="true">
  <tiles:put name="title"  value="My first page" />
  <tiles:put name="header" value="/tutorial/common/header.jsp" />
  <tiles:put name="footer" value="/tutorial/common/footer.jsp" />
  <tiles:put name="menu"   value="/tutorial/basic/menu.jsp" />
  <tiles:put name="body"   value="/tutorial/basic/helloBody.jsp" />
</tiles:insert>
위의 프로그램처럼 호출을 하게 되면 tiles의 기본동작은 /layout/classicLayout.jsp를 템플릿으로 기본으로 하여 처음에 설정된 attribute에 해당하는 put name="title"의 값인 value="My first page"를 classicLayout으로 전달하여 title을 설정하고, include되어질 수 있는 페이지는 tiles:put name="header" value="/tutorial/common/header.jsp"처럼 header영역에 뿌려질 값이 /tutorial/common/header.jsp임을 선언하여 넘길 수가 있다. 그런데~~~!!! 위의 방법이 편한가? 만약 layout을 이용한 페이지가 프로젝트 규모에 따라서 수백본이 될텐데 header, menu, footer의 경우처럼 같은 페이지가 삽입된다고 했을 경우 불필요한 copy-paste가 나타나게 되는 건 불을 보듯 뻔한 일이다. 그렇다면 재사용에 대한 효용성을 극대화시키기 위하여 어떤 방법을 사용하면 될까? Tile에서는 xml파일을 이용하여 layout을 definition할 수 있는 방법을 사용함으로서 같은 부분에 대한 내용을 재사용할 수 있는 효과적인 방법을 제공한다. 페이지를 list형태로 관리하여 각각의 경우에 대한 서로 다른 페이지를 보여줄 수 있는 방법도 존재하지만 그건 각자 알아서 공부하기 바란다. ▶ Definition의 설정 Definition파일을 설정했을 경우 얻어낼 수 있는 효과는 다음과 같다.
  1. 페이지선언에 대한 중앙집중화를 가능하게 한다
  2. 같은 페이지를 계속 선언해야 하는 불필요함을 상속으로서 제거한다.
  3. 파라미터로서 페이지를 호출해야 하는 것을 피한다.
  4. struts-config파일에 forward에 대한 이름으로 정의할 수 있다.
  5. definition attribute에 대한 오버로딩이 가능하다.
  6. 멀티채널 및 국제화에 대한 지원이 가능해진다.
Struts1.1에서는 strut-config.xml파일처럼 tiles에 대한 기본로딩이 가능하도록 구성되어져 있는데 web.xml파일의 servlet-mapping에서 org.apache.struts.tiles.ActionComponentServlet부분의 definitions-config를 이용하여 실제 definition파일의 위치를 지정하여 주면 가능하다. 위의 로딩부분이 들어간 javapattern.info사이트의 web.xml을 잠깐 보자.

<!-- Action Servlet Configuration -->
  <servlet>
	    <servlet-name>action</servlet-name>
	    <servlet-class>org.apache.struts.tiles.ActionComponentServlet</servlet-class>
	    <init-param>
	      <param-name>definitions-config</param-name>
	      <param-value>/WEB-INF/conf/page-definitions.xml</param-value>
	    </init-param>
	    <init-param>
	      <param-name>definitions-debug</param-name>
	      <param-value>1</param-value>
	    </init-param>
	    <init-param>
	      <param-name>application</param-name>
	      <param-value>com.javapattern.resource.ApplicationResources</param-value>
	    </init-param>
	    <init-param>
	      <param-name>config</param-name>
	      <param-value>/WEB-INF/conf/struts-config.xml</param-value>
	    </init-param>
	    <init-param>
	      <param-name>debug</param-name>
	      <param-value>2</param-value>
	    </init-param>
	    <init-param>
	      <param-name>detail</param-name>
	      <param-value>2</param-value>
	    </init-param>
	    <init-param>
	      <param-name>validate</param-name>
	      <param-value>true</param-value>
	    </init-param>
	    <load-on-startup>2</load-on-startup>
  </servlet>
위의 설정에서는 definition-config를 WEB-INF/conf/page-definition.xml 파일로 지정을 했으며 샘플파일을 아래와 같이 설정할 수 있다.

<!-- html definition Mappings  -->
<page-definitions>
  <!-- Definition description  -->
    <definition name="site.mainLayout" path="/tutorial/layout/classicLayout.jsp">
          <put name="title"  value="My First Definition Page" />
          <put name="header" value="/tutorial/common/header.jsp" />
          <put name="footer" value="/tutorial/common/footer.jsp" />
          <put name="menu"   value="/tutorial/common/menu.jsp" />
          <put name="body"   value="/tutorial/basic/hello.jsp" />
    </definition>
</page-definitions>
위에서 선언한 방법은 이미 살펴보았던 classic한 형태의 webpage에 include하는 방식과 별단 다르지가 않지만 가장 큰 특징은 해당 definition name을 정의하여 객체처럼 활용할수 있다는 것이다. 즉 상위 definition을 먼저 정의한 후 아래와 같이 상속을 받아서 사용이 가능하다는 얘기다

  <definition name="site.index.page" extends="site.mainLayout" >
	  <put name="title"  value="Tiles Blank Site Index" />
	  <put name="body"   value="/common/content.jsp" />
  </definition>
설정된 내용을 보게 되면 definition의 이름은 site.index.page라고 하여 site.mainLayout을 상속받아 처리하게 되는데 자바의 객체지향과 같은 개념이라 보면 된다. 즉 실제 site.index.page를 호출했을 경우 나머지 정의된 페이지가 없이 title, body만을 정의하고 있으므로 header, footer, menu는 부모인 site.mainLayout의 속성을 사용하게 되고 body와 title은 실제 자식객체인 site.index.page definition을 사용하게 된다라는 것이다. 그렇다면 저위에 설정된 definition을 어떻게 우리가 보여지게할 template파일에 포함시킬것인가? 그 설정방법은 아래와 같다.

<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>
<tiles:insert definition="site.index.page" flush="true" />
위의 파일은 www.javapattern.info의 index.jsp파일의 설정에 사용된 형태이다. 사실 머리통을 돌려서 다른 조작을 좀 해서 설정을 편하게 했지만 기초내용은 별반 다를 것이 없다. ▶ Conclusion 간단하게 tiles에 대하여 보았으며, 해당 문서는 struts의 tiles part에 포함되어 설명이 아주 자세하게 나와있는 내용이다. 이 글을 읽는 것에만 끝내지 말고, 직접 샘플하나를 만들어보면서 어떻게 적용시킬 수 있을것인가를 생각해보면 아주 다양하게 처리할 수 있는 방법이 계속 꼬리에 꼬리를 물게 될것이라 생각한다. 놀새~도 이미 이러한 내용은 2001년 말에 petstore를 분석하면서 spider를 만들때 적용을 했었는데 이럴줄 알았으며 apache contributor로 메일이나 한통 보낼걸 그랬다라는 생각이 많이 든다.. ^^ 건투를 빕니다.~!
 
1
References
 
Copyright ⓒ 2003 www.javapattern.info & www.jlook.com, an jLOOK co.,LTD