[난 왜 Tiles Framework 란걸 찾게 되었는가?]
jsp파일로 화면을 구성하다보면 header/footer같은 공통적인 소스 들이 존재한다. 공통적인 부분은 jsp파일로 따로 분리하고, 각 화면에 해당하는jsp파일에 header/footer.jsp를 include하는 방식으로 중복되는 소스를 줄이는 방식을 이용한다.
그런데, 일단 각 화면jsp파일마다 모두 header/footer.jsp파일을 include해주는것도 귀찮지만 만약 페이지의 레이아웃이 바뀐다면 jsp파일 수 만큼 include를 수정해주는 작업을 해줘야하는 수고로움이 생긴다.
따라서! 각 화면jsp파일마다 따로 header/footer.jsp를 include해주지 않고 오로지 각 화면에 해당하는 소스만 작성하고 싶었고, 페이지의 레이아웃은 한 곳에서 설정하여 관리할 수 있도록 하고 싶었다. 이걸 가능하게 해주는게 Tiles Framework이다.
[Spring프로젝트에 Tiles Framework 적용방법]
요약하면 아래 순서대로 진행된다.
1. pom.xml에 관련 라이브러리 추가
2. servlet-context.xml에 view resolver 수정 및 추가, tiles관련 설정파일 경로 명시
- Spring에서 DispatcherServlet이 view resolver를 통해 view단에 보여줄 화면을 구성하게 되는데, 이때 기존에
사용하던 InternalResourceViewResolver에서 UrlBasedViewResolver를 첫번째로 고려하도록 수정하는 것이다.
- 브라우저에서 서버로 url호출시 처리 과정의 우선순위가 아래처럼 변경되는 것이다.
url 호출 => @ReqeustMapping => Tiles ViewResolver => InternalResourceViewResolver
3. tiles.xml 설정파일 작성( tiles framework의 설정파일 )
4. 기본 템플릿이될 jsp 작성
5. 화면 테스트
1. pom.xml에 관련 라이브러리 추가
- <properties> 태그 안에 tiles 버전을 명시해준다.
<properties>
<java-version>1.8</java-version>
<org.springframework-version>5.0.7.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
<!-- tiles관련 추가 -->
<org.apache.tiles-version>3.0.5</org.apache.tiles-version>
</properties>
- tiles관련 라이브러리를 dependcy태그로 추가해준다.
<!-- Tiles Framework 관련 -->
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-servlet</artifactId>
<version>${org.apache.tiles-version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-api</artifactId>
<version>${org.apache.tiles-version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>${org.apache.tiles-version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>${org.apache.tiles-version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-template</artifactId>
<version>${org.apache.tiles-version}</version>
</dependency>
<!-- Tiles Framework 관련 -->
2. servlet-context.xml에 view rewolver 수정 및 추가, tiles관련 설정파일 경로 명시
- 기존 view resolver인 InternalResourceViewResolver의 우선순위를 첫번째가 아닌 2(두번째)로 바꿔준다.
<!-- 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" />
<!-- 기존 view resolver의 우선순위를 2로 해준다. -->
<beans:property name="order" value="2" />
</beans:bean>
-tiles 관련 설정파일인 tiles.xml 경로 명시 및 UrlBasedViewResolver를 추가하고 우선순위를 1(첫번째)로 해준다.
<!-- Tiles 관련 추가 내용-->
<!-- Tiles관련 설정파일 -->
<beans:bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<beans:property name="definitions">
<beans:list>
<beans:value>/WEB-INF/tiles/tiles.xml</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<!-- Tiles의 우선순위를 1로 해준다. -->
<beans:bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<beans:property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
<beans:property name="order" value="1" />
</beans:bean>
3. tiles.xml 설정파일 작성
<!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>
<!-- 1. 기본적인 템플릿을 생성한다.
header, body, footer를 가진 teamplate.jsp라는 기본 레이아웃을 정의한다.
이 정의된 레이아웃의 name속성인 base를 상속하여 추가적으로 여러 tiles들을 만들수 있다.
-->
<definition name="base" template="/WEB-INF/tiles/template.jsp">
<put-attribute name="header" value="/WEB-INF/tiles/header.jsp" />
<put-attribute name="body" value="" />
<put-attribute name="footer" value="/WEB-INF/tiles/footer.jsp" />
</definition>
<!-- 2. base를 상속받은것.
즉, body부분만 설정한 경로대로 갈아 끼우고, 나머지 header, footer는 base의 형식대로 상속받아 오는 것이다. -->
<definition name="*" extends="base">
<put-attribute name="body" value="/WEB-INF/views/{1}.jsp" />
</definition>
<definition name="*/*" extends="base">
<put-attribute name="body" value="/WEB-INF/views/{1}/{2}.jsp" />
</definition>
<definition name="*/*/*" extends="base">
<put-attribute name="body" value="/WEB-INF/views/{1}/{2}/{3}.jsp" />
</definition>
<!-- 메뉴 미표시
: 페이지 중 로그인페이지 같은건 보통 header, footer모두를 레이아웃으로 가지지 않을 것이다.
다만, header에 js라이브러리등을 포함하고 있을 것이므로 이런 특정경로의 jsp파일들은 header만 상속받고 footer는 사용하지 않는 방식으로 할 수 있다.
-->
<definition name="baseEmpty" template="/WEB-INF/tiles/templateEmpty.jsp">
</definition>
<definition name="*.part" extends="baseEmpty">
<put-attribute name="body" value="/WEB-INF/views/{1}.jsp" />
</definition>
<definition name="*/*.part" extends="baseEmpty">
<put-attribute name="body" value="/WEB-INF/views/{1}/{2}.jsp" />
</definition>
<definition name="*/*/*.part" extends="baseEmpty">
<put-attribute name="body" value="/WEB-INF/views/{1}/{2}/{3}.jsp" />
</definition>
</tiles-definitions>
4. 기본 템플릿 jsp파일 template.jsp 작성
위 3번에서 tiles.xml에서 <definition>태그에서 name속성에 작성한 header, footer에 해당하는 value값에 있는경로의
jsp파일이 <tiles:insertAttributes>태그의 name속성에 사용되는것이다.
즉, header, body, footer 라는 레이아웃으로 템플릿을 구성한 것이다.
<%@ 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 lang="ko">
<head>
<meta charset="UTF-8">
<title>제목</title>
</head>
<body>
<%-- <div id="header"><tiles:insertAttribute name="header" /></div>
<div id="body"><tiles:insertAttribute name="body" /></div>
<div id="footer"><tiles:insertAttribute name="footer" /></div>
--%>
<tiles:insertAttribute name="header" />
<tiles:insertAttribute name="body" />
<tiles:insertAttribute name="footer" />
<script type="text/javascript">
$(function() {
});
</script>
</body>
</html>
5. 위 3번에서 작성한 footer.jsp와 header.jsp를 경로에 맞게 추해준다.
6. 화면에서 테스트
header, footer.jsp사이에 body부분에 해당하는 list.jsp파일이 위치한것을 확인할 수 있다.
참고로 아래 list.jsp 소스를 보면 header.jsp, footer.jsp를 include하는 부분이 없는걸 확인할 수 있다. 다만 목록을 보여주기위한 소스만 있게된다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">BOARD LIST PAGE</h1>
</div>
<!-- /.col-lg-12 -->
</div>
<!-- 등록버튼 -->
<div class="row">
<div class="col-lg-12">
<button type="button" id="btnRegister" class="btn btn-outline btn-primary btn-xs pull-right">Register New Board</button>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<p></p>
</div>
</div>
<!-- /.row -->
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<!-- /.panel-heading -->
<div class="panel-body">
<table width="100%" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>#번호</th>
<th>제목</th>
<th>작가</th>
<th>내용</th>
<th>업데이트일자</th>
<th>등록일자</th>
</tr>
</thead>
<tbody>
<c:forEach var="board" items="${boardList}">
<tr>
<td><c:out value="${board.bno}" /></td>
<td><a href="#"><c:out value="${board.title}" /></a></td>
<td><c:out value="${board.writer}" /></td>
<td><c:out value="${board.content}" /></td>
<td><fmt:formatDate pattern ="yyyy-MM-dd hh:mm:ss" value="${board.updateDate}" /></td>
<td><fmt:formatDate pattern ="yyyy-MM-dd hh:mm:ss" value="${board.regDate}" /></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<script src="/resources/js/board/list.js"></script>
각 jsp파일에서 사용하는 js파일의 경우 가장 하단에 script태그로 포함시키고 있다. 이 또한 따로 각 jsp파일마다 명시해주지 않아도 되도록 세팅을 하는 방법을 찾아봐야할 것 같다.
'스프링 프레임워크 > Spring+Oracle+MyBatis 게시판 프로젝트' 카테고리의 다른 글
[Spring+Oracle+MyBatis]3. 오라클 테스트할 테이블, 더미데이터 생성 (0) | 2019.05.10 |
---|---|
[Spring+Oracle+MyBatis]2. 프로젝트의 JDBC 연결 (0) | 2019.05.08 |
[Spring+Oracle+MyBatis]1. Spring MVC 프로젝트 생성 (0) | 2019.05.08 |