웹페이지에서 상단 메뉴나 하단의 홈페이지 정보같은 정보는 여러 페이지에서 중복적으로 사용되는 경우가 많다.
예를 들면 쇼핑몰 사이트인 11번가에서도 대부분의 페이지의 상/하단부가 아래와 같이 구성되어있다.
< 페이지 상단 >
< 페이지 하단 >
페이지 수가 적다면 상관이 없지만 페이지가 50개 100개 이상이 된다면 상/하단의 내용이 바뀔 때 그만큼의 수정작업이 필요하다.
이와 같은 소스의 중복을 피하고 유지보수를 용이하게 하기위해 layout을 나누어 붙일 수 있는 tiles라는 기능이 있다.
요번 포스트에서는 이런 형식으로 header와 footer는 그대로 두되, 가운데 내용물만 바꾸는 모양을 만들어보려고 한다.
1. maven(pom.xml)
<dependency> <groupid>org.apache.tiles</groupid> <artifactid>tiles-extras</artifactid> <version>3.0.0</version> </dependency> <dependency> <groupid>org.apache.tiles</groupid> <artifactid>tiles-jsp</artifactid> <version>3.0.0</version> </dependency> <dependency> <groupid>org.apache.tiles</groupid> <artifactid>tiles-servlet</artifactid> <version>3.0.0</version> </dependency>
- maven에서 위의 tiles에 관련된 라이브러를 다운받는다. 단순한 tiles 기능만 사용한다면 extras만 받아도 상관없다고 한다.
- tiles3을 이용한다. tiles2와의 차이는 여기를 참고하길바란다. iles3을 사용하기 위해서는 spring 3.2이상 버전을 사용해야한다.
<properties>
<java-version>1.6</java-version>
<org.springframework-version>3.2.2.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
<org.apache.tiles.version>3.0.0</org.apache.tiles.version>
</properties>
- 3.1.1.RELEASE를 사용중이었다면 3.2.2로 바꿔주자..
2. servlet-context.xml
<!-- tiles -->
<beans:bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<beans:property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/>
<beans:property name="order" value="0" />
</beans:bean>
<beans:bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<beans:property name="definitions">
<beans:value>/WEB-INF/tiles/tiles.xml</beans:value>
</beans:property>
</beans:bean>
<!-- 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="1" />
</beans:bean>
- tiles를 동적으로 mapping하지 않는다면 UrlBasedViewResolver bean을 굳이 추가할 필요는 없다.
- 동적 mapping을 사용한다면 UrlBasedViewResolver bean을 추가하고 view Resolver의 순서를 바꿔준다. (ViewResolver는 아래에서 추가설명)
- 다수의 ViewResolver가 존재하는경우 InternalResourceViewResolver는 항상 가장 낮은 우선순위여야 하기 때문에 order를 지정해준다.
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>
①
<definition name="base" template="/WEB-INF/views/layout/template.jsp">
<put-attribute name="header" value="/WEB-INF/views/layout/header.jsp"/>
<put-attribute name="footer" value="/WEB-INF/views/layout/footer.jsp"/>
</definition>
②
<definition name="/" extends="base">
<put-attribute name="body" value="/WEB-INF/views/index.jsp"/>
</definition>
<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>
</tiles-definitions>
①
- definition에서 화면의 기초가 될 template을 선택하고 해당 template에서 쓰일 attribute를 추가한다.
②
- definition에서 servlet경로(name)와 매칭시킬 view를 정한다. extends를 사용하여 상속 받으면 기존에 정의된 view의 사용이 가능하다.
- 정적 mapping으로 /(ROOT)일 경우 /WEB-INF/views/index.jsp를 view로 가져온다.
③
- 동적 mapping으로 *하나에 와일드카드({1},{2},{3})이 mapping된다. /admin/info/update의 경로라면 /WEB-INF/views/admin/info/update.jsp view를 가져온다.
- ? : 한 글자, * : 아무글자나, [abc] : abc로 시작
4. View
template.jsp
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="/resources/css/index.css">
</head>
<body>
<tiles:insertAttribute name="header" />
<div id="container">
<tiles:insertAttribute name="body" />
</div>
<tiles:insertAttribute name="footer" />
</body>
</html>
- tiles를 이용한 view 객체 생성에 기본이 될 template.jsp 를 구성하고 <tiles:insertAttribute name="attribute이름" /> 을 넣어 위치를 정한다.
header.jsp
<div id="header">
<nav class="navbar navbar-default">
<div class="container-fluid">
.......
</div>
</nav>
</div>
footer.jsp
<div id="footer">
<blockquote class="blockquote-reverse">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
<footer>Someone famous in <cite title="Source Title">Source Title</cite></footer>
</blockquote>
</div>
- 모든 페이지에서 기본적으로 사용될 부분
index.jsp
<div id="content">
<div class="panel panel-default">
<div class="panel-body">
Basic panel example
</div>
</div>
</div>
/member/member_join.jsp
<div id="content">
<form id="member_join_form" class="width500">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Sign up</h3>
</div>
<div class="panel-body">
<div class="form-group">
.....
</div>
</div>
</div>
<div class="text-right">
<button type="submit" class="btn btn-primary">Submit</button>
<button type="submit" class="btn btn-default">Cancel</button>
</div>
</form>
</div>
- 페이지마다 바뀌는 부분
5. Controller
MainController
@Controller
public class MainController {
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home() {
return "index";
}
}
MemberController
@Controller
@RequestMapping(value="/member")
public class MemberController {
@RequestMapping(value="/join", method=RequestMethod.GET)
public String join(){
return "/member/member_join";
}
}
- Controller에서 URL 매핑을 해준다.
6. Project Directory
- 최종적인 프로젝트 구성요소
7. Result
URL : /
------------------------------------------------------------------------------------------------------
URL : /member/join
- 가운데 container 부분만 바뀌는 것을 확인할 수 있다.
+ View Resolver
- View Resolver는 Spring의 DispatcherServlet이 Controller의 응답 결과를 가져올 때, 어떤 방식으로 view 객체를 가져올지 정하고 해당 객체를 생성한다.
- View Resolver를 구현한 클래스는 InternalResourceViewResolver, BeanNameViewResolver, XmlViewResolver, UrlBasedViewResolver 등이 있다.
- DispatcherServlet은 여러개의 ViewResolver를 가질 수 있는데, 'order' property에 따라 어떤 ViewResolver를 결정할지 우선순위를 정할 수 있다. 우선순위를 명시하지 않으면 가장 낮은 우선순위를 가진다.
- 우선순위가 높은 ViewResolver에게 View 객체를 요청하는데, 만약 null을 리턴한다면 그 다음 우선순위의 ViewResolver에게 객체를 요청하게 된다.
- InternalResourceViewResolver는 항상 mapping되는 view 객체를 리턴하고, 없다고 null을 반환하지 않으므로 항상 가장 낮은 우선순위로 두어야한다.
'Programming > >> Spring' 카테고리의 다른 글
[Spring] Spring 다국어 지원 (0) | 2015.12.02 |
---|---|
[Spring] Spring + Hibernate 설정 방법 고찰? (1) | 2015.11.24 |
[Spring] Spring + Hibernate4 + MySQL 설정 (0) | 2015.11.22 |
[Java] spring+mybatis+mysql 연동 (0) | 2014.08.17 |
[Spring] spring mvc 프로젝트 생성 (0) | 2014.08.17 |
댓글