Tiles 프레임워크🔎
- 레이아웃 프레임워크
- 페이지간 공통되는 레이아웃(뼈대)을 구성하고 관리하는 기술이다.
- 이전 레이아웃 작업을 include로 작업하여 페이지를 분리시켜서 최대한 재사용하였다.
- <@% include file = "재사용할 조각페이지" %>
- 하지만, include는 조직적인거나 대중적인 작업을 하기에는 부족한 면이 많았다.
- 규모가 있는 작업을 할 때는 라이브러리나 프레임워크를 사용한다. 그 중 Tiles 프레임워크가 스프링과 연동을 하여 오랫동안 사용한 프레임워크이다.
- tiles를 사용해보면 다른 디자인 프레임워크와 비슷하여 크게 어렵지않을 것이다.
레이아웃🔎
상위 메뉴는 고정이며, 회원 / 관리자마다 사이드메뉴를 다르게 출력한다.
구현 기능🔎
1. 메인 (index.do)
2. 회원
- 회원정보(member/info.do)
- 활동내역(member/history.do)
- 즐겨찾기(member/favorite.do)
3. 관리자
- 로그(admin/log.do)
- 환경설정(admin/setting.do)
파일 구성🔎
패키지명/경로 | 파일명 | 역할 |
com.test.controller | ||
MainController.java | ||
MemberController.java | ||
AdminController.java | ||
WEB-INF/views | ||
tiles.xml | 조각페이지 선언 | |
WEB-INF/views/member | ||
info.jsp | 회원 정보 | |
history.jsp | 활동 내역 | |
favorite.jsp | 즐겨찾기 | |
WEB-INF/views/admin | ||
log.jsp | 로그 | |
setting.jsp | 환경설정 | |
WEB-INF/views/layout | ||
index.jsp | 메인화면 | |
layout.jsp | ||
WEB-INF/inc | ||
main_menu.jsp | 상단 메뉴 | |
member_menu | 회원용 사이드 메뉴 | |
admin_menu | 관리자용 사이드 메뉴 | |
asset.jsp | 디자인 | |
환경설정🔎
1. 버전 설정 - pom.xml
자바 버전 11, Spring 버전 5.0.7
2. 의존성추가 - pom.xml
<!-- Tiles -->
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-api</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-servlet</artifactId>
<version>3.0.8</version>
</dependency>
3. servlet-context.xml
1) 기존 뷰리졸버(InternalResourceViewResolver) 코드 삭제
2) 아래 UrlBasedViewResolver 뷰리졸버 코드 추가
UrlBasedViewResolver 는 JSP를 찾지않고 다른 구성요소를 찾아 tiles를 운영할 수 있도록 도와준다.
config에서 xml 파일 경로를 지정한다.
<beans:bean id="tielsViewResolver"
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>
<beans:bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<beans:property name="definitions">
<beans:list>
<beans:value>/WEB-INF/tiles.xml</beans:value>
</beans:list>
</beans:property>
</beans:bean>
3) component-scan 추가
<context:component-scan base-package="com.test.controller" />
- tiles.xml ★
조각 페이지(=attribute) 선언
기존 뷰 리졸버를 삭제하여 JSP 페이지명으로 찾지못한다.
새롭게 UrlBasedViewResolver 로 교체를 하여 controller의 반환값(문자열)이 definition 의 이름을 뜻한다.
이 definition은 tiles.xml에서 정의하고 관리한다.
컨트롤러가 JSP를 호출하는 방식이 definition을 호출하고, 그 definition에 정의된 파일을 호출하는 방식으로 변경되었다.
ties.xml에 definition을 정의하는 것을 조각페이지 선언한다고도 한다.
이 조각 페이지는 include의 역할과 유사한 역할로 공통으로 들어가는 부분을 따로 분리하여 재사용한다.
definition에 정의된 template를 레이아웃 페이지라고 불린다.
더 복잡하고 비효율적인 것처럼 보일 수 있지만, 기존 작업을 효과적으로 수행할 수 있도록 도와준다.
defintion 하나는 view 하나라고 생각하면 된다.
<?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 name="index" template="/WEB-INF/views/layout/index.jsp">
<put-attribute name="asset" value="/WEB-INF/inc/asset.jsp"></put-attribute>
<put-attribute name="main_menu" value="/WEB-INF/inc/main_menu.jsp"></put-attribute>
</definition>
</tiles-definitions>
<definition>으로 사용될 타일 정의를 한다.
"index"라는 이름의 타일을 정의하고, 타일은 layout 폴더로 관리하기에 index.jsp를 layout 폴더에 넣고 "/WEB-INF/views/layout/index.jsp"라는 템플릿을 기반으로 정의한다.
<put-attribute> 태그로 타일에 포함될 속성을 정의한다.
"asset" 이름의 속성으로 asset.jsp 를 설정하고, "main_menu" 이름의 속성으로 main_menu.jsp를 설정하였다.
index.jsp에서 asset.jsp, main_menu.jsp 를 호출할 수 있다.
레이아웃 통합
<definition name="*.*" template="/WEB-INF/views/layout/layout.jsp">
<put-attribute name="asset" value="/WEB-INF/inc/asset.jsp"></put-attribute>
<put-attribute name="main_menu" value="/WEB-INF/inc/main_menu.jsp"></put-attribute>
<put-attribute name="sub_menu" value="/WEB-INF/inc/{1}_menu.jsp"></put-attribute>
<put-attribute name="content" value="/WEB-INF/views/{1}/{2}.jsp"></put-attribute>
</definition>
와일드카드(*)를 사용하여 어떠한 URL 패턴이라도 해당할 수 있도록 설정했다.
"content"라는 이름의 속성을 정의하고, 값으로 "/WEB-INF/views/{1}/{2}.jsp"를 설정하였는데, 여기서 {1}과 {2}는 URL에서 추출한 첫 번째와 두 번째 패스 변수의 값을 나타낸다.
이렇게 정의를 하면 다양한 URL 패턴에 대응하여 동적으로 레이아웃을 생성할 수 있다.
구현 코드🔎
- 초기 세팅
MainController.java
package com.test.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class MainController {
}
MemberController.java
package com.test.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/member")
public class MemberController {
}
}
AdminController.java
package com.test.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/admin")
public class AdminController {
}
asset.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<link rel="stylesheet" href="https://me2.do/5BvBFJ57">
<script src="https://code.jquery.com/jquery-1.12.4.js" ></script>
main_menu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<header>
<h1>Tiles</h1>
<ul>
<li><a href="/tiles/index.do">Home</a></li>
<li><a href="/tiles/member/info.do">Member</a></li>
<li><a href="/tiles/admin/log.do">Admin</a></li>
</ul>
</header>
member_menu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<ul>
<li><a href="/tiles/member/info.do">회원정보</a></li>
<li><a href="/tiles/member/history.do">활동내역</a></li>
<li><a href="/tiles/member/favorite.do">즐겨찾기</a></li>
</ul>
admin_menu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<ul>
<li><a href="/tiles/admin/log.do">로그</a></li>
<li><a href="/tiles/admin/setting.do">환경설정</a></li>
</ul>
- 메인화면
MainController
@GetMapping(value = "/index.do")
public String index(Model model) {
return "index";
}
tiles.xml 에서 정의한 <difinition> name값으로 호출한다.
index.jsp
<%@ 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="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TilesTest</title>
<tiles:insertAttribute name="asset" />
</head>
<body>
<!-- index.jsp -->
<tiles:insertAttribute name="main_menu" />
<main>
<h1>시작 페이지</h1>
</main>
</body>
</html>
<tiles:insertAttribute name="속성 이름" />
타일에 포함될 속성을 정의한 이름으로 속성을 호출한다. 위에서 "index" 타일에 "asset", "main_menu"를 속성으로 정의하였으므로 insertAttribute로 호출할 수 있다.
- 회원_회원정보
MemberController.java
@GetMapping(value = "/info.do")
public String info(Model model) {
return "member.info";
}
tiles.xml 에서 정의한 name값으로 호출하는데 위 코드는 </definition name="*.*">와 호출한 것과 같다.
.(온점)을 기준으로 별표로 인식한다.
layout.jsp
<%@ 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="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TilesTest</title>
<tiles:insertAttribute name="asset" />
</head>
<body>
<!-- layout/layout.jsp -->
<tiles:insertAttribute name="main_menu" />
<tiles:insertAttribute name="sub_menu" />
<tiles:insertAttribute name="content" />
</body>
</html>
MemberController.java에서 "member.info" 으로 "*.*"를 호출하여 layout.jsp이 응답하게 되었다.
첫번째 인자로 member 두번째 인자로 info를 넘겼으므로 "sub_menu"에는 member_menu.jsp가 호출되며, "content"는 info.jsp가 호출된다.
info.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<main>
<h1>
회원 <small>회원 정보</small>
</h1>
<div class="message" title="홍길동">일반 회원입니다.</div>
</main>
- 회원_활동내역
MemberController.java
@GetMapping(value = "/history.do")
public String history(Model model) {
return "member.history";
}
위의 회원정보와 같이 layout를 호출하게 되고 인자값에 따라 레이아웃 템플릿을 호출한다.
위 코드는 member_menu.jsp와 history.jsp로 조합된 layout.jsp를 호출한다.
layout.jsp는 내용이 같으므로 history.jsp만 추가한다.
history.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<main>
<h1>
회원 <small>활동내역</small>
</h1>
<div class="list">
<div>10:06:10 프로젝트 생성</div>
<div>10:07:10 pom.xml 구성</div>
<div>10:10:20 servlet-context.xml 수정</div>
</div>
</main>
DB 생략으로 그냥 PCData로 기재하였다.
- 회원_즐겨찾기
MemberController.java
@GetMapping(value = "/favorite.do")
public String favorite(Model model) {
return "member.favorite";
}
위 설명과 동일하다.
favorite.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<main>
<h1>
회원 <small>즐겨찾기</small>
</h1>
<div>
<div>
<a href="#">구글</a>
</div>
<div>
<a href="#">아마존</a>
</div>
<div>
<a href="#">깃허브</a>
</div>
</div>
</main>
- 관리자_로그
AdminController.java
@GetMapping(value = "/log.do")
public String log(Model model) {
return "admin.log";
}
위 설명과 동일하다.
log.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<main>
<h1>
관리자 <small>로그</small>
</h1>
<pre style="padding: 1rem;">
INFO : org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/resources/**] onto handler 'org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0'
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'appServlet': initialization completed in 1329 ms
11월 27, 2023 9:58:17 오전 org.apache.coyote.AbstractProtocol start
INFO: 프로토콜 핸들러 ["http-nio-8090"]을(를) 시작합니다.
11월 27, 2023 9:58:17 오전 org.apache.catalina.startup.Catalina start
INFO: 서버가 [3981] 밀리초 내에 시작되었습니다.
</pre>
</main>
- 관리자_환경설정
AdminController.java
@GetMapping(value = "/setting.do")
public String setting(Model model) {
return "admin.setting";
}
setting.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<main>
<h1>관리자 <small>환경설정</small></h1>
<div>
<button class="setting">권한 설정하기</button>
</div>
</main>
템플릿 레이아웃마다 definition을 정의하면, 웹 페이지의 일부를 템플릿화하고, 이를 여러 페이지에서 재사용할 수 있다.
회원의 info, history, favorite, 관리자의 log, setting 처럼 주업무에 집중할 수 있는 환경을 만들어준다.
'Spring' 카테고리의 다른 글
[Spring] Apache Commons IO 라이브러리(2) : 다중 file 입출력 (0) | 2023.11.29 |
---|---|
[Spring] Apache Commons IO 라이브러리(1) : file 입출력 (0) | 2023.11.29 |
[Spring] Spring MVC 프로젝트에 MyBatis 적용하기 : 코드 조각 관리 게시판 (0) | 2023.11.29 |
[Spring] MyBatis 쿼리문 작성하기 (0) | 2023.11.27 |
[Spring] MyBatis 와 Spring 연동하기(2) : DBCP 사용하기 (0) | 2023.11.27 |