🌿Tiles
페이지를 만들다 보면 공통적으로 생기는 디자인적인 뼈대가 있다. Tiles는 이때 사용할 수 있는 레이아웃 프레임워크이다.
이전에는 레이아웃을 <@% include file="재사용할 조각 페이지"%>로 페이지를 최대한 분리시켜서 반복되는 디자인 요소를 구성했다.
레이아웃을 서포트하는 프레임워크를 사용하면 조직적이고 대규모적인 작업을 할 수 있다.
Tiles는 include를 대신하여 페이지의 레이아웃을 구성하고 관리하는 기술이다.
구현 기능
- 메인(index.do)
회원
- 회원정보(member/info.do)
- 활동내역(member/history.do)
- 즐겨찾기(member/favorite.do)
관리자
- 로그(admin/log.do)
- 환경설정(admin/setting.do)
🌿Tiles를 사용하지 않고 레이아웃 구현
파일 생성
com.test.comtroller
- MainController.java
- MemberController.java
- AdminController.java
views
- index.jsp
- member
- info.jsp
- history.jsp
- favorite.jsp
- admin
- log.jsp
- setting.jsp
inc
- main_menu.jsp
- member_menu.jsp
- admin_menu.jsp
- asset.jsp
전체 코드
servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- 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" />
</beans:bean>
<context:component-scan base-package="com.test.nontiles" />
<context:component-scan base-package="com.test.controller" />
</beans:beans>
com.test.controller를 추가해 주었다.
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 {
@GetMapping(value = "/index.do")
public String index(Model model) {
return "index";
}
}
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 {
@GetMapping(value = "/info.do")
public String info(Model model) {
return "member/info";
}
@GetMapping(value = "/history.do")
public String history(Model model) {
return "member/history";
}
@GetMapping(value = "/favorite.do")
public String favorite(Model model) {
return "member/favorite";
}
}
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 {
@GetMapping(value = "/log.do")
public String log(Model model) {
return "admin/log";
}
@GetMapping(value = "/setting.do")
public String setting(Model model) {
return "admin/setting";
}
}
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"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<%@ include file="/WEB-INF/inc/asset.jsp"%>
<style>
</style>
</head>
<body>
<!-- index.jsp -->
<%@ include file="/WEB-INF/inc/main_menu.jsp"%> <!-- main_menu -->
<main>
<h1>시작 페이지</h1>
</main>
<script>
</script>
</body>
</html>
헤더로 모든 태그를 뺄 수 있지만, 이중 li 태그만 빼는 경우도 있다.
헤더 제목이 관리자 쪽으로 들어가면 부제가 Tiles "member"처럼 붙을 수 있기 때문이다. 그래서 통째로 header 조각 페이지로 빼버리면 추가적인 프로그래밍 처리가 필요하므로 변치 않는 부분만 조각 페이지로 빼는 방법을 사용할 수 있다.
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" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<%@ include file="/WEB-INF/inc/asset.jsp" %>
<style>
</style>
</head>
<body>
<!-- member > info.jsp -->
<%@ include file="/WEB-INF/inc/main_menu.jsp" %> <!-- main_menu -->
<%@ include file="/WEB-INF/inc/member_menu.jsp" %> <!-- member_menu -->
<main>
<h1>회원 <small>회원정보</small></h1>
<div class="message" title="Isaac">
일반 회원입니다.
</div>
</main>
<script>
</script>
</body>
</html>
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" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<%@ include file="/WEB-INF/inc/asset.jsp" %>
<style>
</style>
</head>
<body>
<!-- member > history.jsp -->
<%@ include file="/WEB-INF/inc/main_menu.jsp" %> <!-- main_menu -->
<%@ include file="/WEB-INF/inc/member_menu.jsp" %> <!-- member_menu -->
<main>
<h1>회원 <small>활동내역</small></h1>
<div class="list">
<div>10:00:00 프로젝트 생성</div>
</div>
</main>
<script>
</script>
</body>
</html>
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" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<%@ include file="/WEB-INF/inc/asset.jsp" %>
<style>
</style>
</head>
<body>
<!-- member > favorite.jsp -->
<%@ include file="/WEB-INF/inc/main_menu.jsp" %> <!-- main_menu -->
<%@ include file="/WEB-INF/inc/member_menu.jsp" %> <!-- member_menu -->
<main>
<h1>회원 <small>즐겨찾기</small></h1>
<div class="list">
<div><a href="#">구글</a></div>
<div><a href="#">아마존</a></div>
<div><a href="#">깃헙</a></div>
</div>
</main>
<script>
</script>
</body>
</html>
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" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<%@ include file="/WEB-INF/inc/asset.jsp" %>
<style>
pre {
padding: 1rem;
}
</style>
</head>
<body>
<!-- admin > log.jsp -->
<%@ include file="/WEB-INF/inc/main_menu.jsp" %> <!-- main_menu -->
<%@ include file="/WEB-INF/inc/admin_menu.jsp" %> <!-- admin_menu -->
<main>
<h1>관리자 <small>로그</small></h1>
<pre>
11월 27, 2023 10:09:56 오전 org.apache.coyote.AbstractProtocol start
INFO: 프로토콜 핸들러 ["http-nio-8090"]을(를) 시작합니다.
11월 27, 2023 10:09:56 오전 org.apache.catalina.startup.Catalina start
INFO: 서버가 [6708] 밀리초 내에 시작되었습니다.
</pre>
</main>
<script>
</script>
</body>
</html>
<pre>태그를 만들어서 로그를 표현한다.
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" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<%@ include file="/WEB-INF/inc/asset.jsp" %>
<style>
</style>
</head>
<body>
<!-- admin > setting.jsp -->
<%@ include file="/WEB-INF/inc/main_menu.jsp" %> <!-- main_menu -->
<%@ include file="/WEB-INF/inc/admin_menu.jsp" %> <!-- admin_menu -->
<main>
<h1>관리자 <small>환경설정</small></h1>
<div>
<button class="setting">권한 설정하기</button>
</div>
</main>
<script>
</script>
</body>
</html>
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" %>
<!-- inc > main_menu -->
<header>
<h1>Tiles</h1>
<ul>
<li><a href="/nontiles/index.do">Home</a></li>
<li><a href="/nontiles/member/info.do">Member</a></li>
<li><a href="/nontiles/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"%>
<!-- inc > member_menu.jsp -->
<ul>
<li><a href="/nontiles/member/info.do">회원정보</a></li>
<li><a href="/nontiles/member/history.do">활동내역</a></li>
<li><a href="/nontiles/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"%>
<!-- inc > admin_menu -->
<ul>
<li><a href="/nontiles/admin/log.do">로그</a></li>
<li><a href="/nontiles/admin/setting.do">환경설정</a></li>
</ul>
asset.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<title>NonTilesTest</title>
<!-- asset.jsp -->
<link rel="stylesheet" href="https://me2.do/5BvBFJ57">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
🌿Tiles를 사용하여 레이아웃 구현
Tiles에서는 더 이상 <%@include%> 태그를 사용하지 않는다.
기존에 만든 페이지는 주 업무와 보조 업무를 알아보기 힘들다. Tiles는 주 업무와 보조 업무를 구분할 수 있다는 장점이 있다.
🍃Tiles 설정
위 글을 참고하여 Java(JDK), Spring 버전 변경 등의 설정을 한다.
추가로 의존성 추가와 servlet-context 수정 작업이 필요하다.
pom.xml: 4개 의존성 추가
<!-- 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>
tiles는 apache에서 만든 것으로, 3.0.8이 마지막 버전이다.
servlet-context.xml
<!-- 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" />
</beans:bean>
-->
<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>
<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>
컨트롤러에서 JSP를 호출할 때 접두어를 붙여주는 역할을 하는데, 이를 지운다. 그리고 이를 대체하는 다른 View Resolver를 추가로 만든다.
이게 문자열을 리턴하면 jsp를 찾는 게 아니라 다른 걸 찾아준다.
tiles taglib
<%@taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
tiles 라이브러리를 사용하기 위해서는 taglib를 추가해야 한다.
⭐tiles.xml
재사용성을 고려하지 않은 경우
<?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="test" template="/WEB-INF/views/test.jsp">
<!-- 조각 페이지(attribute) 선언 -->
<put-attribute name="main_menu" value="/WEB-INF/inc/main_menu.jsp"></put-attribute>
</definition>
<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>
<definition name="info" template="/WEB-INF/views/layout/member.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="member_menu" value="/WEB-INF/inc/member_menu.jsp"></put-attribute>
<put-attribute name="content" value="/WEB-INF/views/member/info.jsp"></put-attribute>
</definition>
<definition name="history" template="/WEB-INF/views/layout/member.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="member_menu" value="/WEB-INF/inc/member_menu.jsp"></put-attribute>
<put-attribute name="content" value="/WEB-INF/views/member/history.jsp"></put-attribute>
</definition>
<definition name="favorite" template="/WEB-INF/views/layout/member.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="member_menu" value="/WEB-INF/inc/member_menu.jsp"></put-attribute>
<put-attribute name="content" value="/WEB-INF/views/member/favorite.jsp"></put-attribute>
</definition>
<definition name="log" template="/WEB-INF/views/layout/admin.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="member_menu" value="/WEB-INF/inc/admin_menu.jsp"></put-attribute>
<put-attribute name="content" value="/WEB-INF/views/admin/log.jsp"></put-attribute>
</definition>
<definition name="setting" template="/WEB-INF/views/layout/admin.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="member_menu" value="/WEB-INF/inc/admin_menu.jsp"></put-attribute>
<put-attribute name="content" value="/WEB-INF/views/admin/setting.jsp"></put-attribute>
</definition>
</tiles-definitions>
재사용성을 고려한 경우 1
<?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="test" template="/WEB-INF/views/test.jsp">
<!-- 조각 페이지(attribute) 선언 -->
<put-attribute name="main_menu" value="/WEB-INF/inc/main_menu.jsp"></put-attribute>
</definition>
<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>
<definition name="member.*" template="/WEB-INF/views/layout/member.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="member_menu" value="/WEB-INF/inc/member_menu.jsp"></put-attribute>
<put-attribute name="content" value="/WEB-INF/views/member/{1}.jsp"></put-attribute>
</definition>
<definition name="admin.*" template="/WEB-INF/views/layout/admin.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="member_menu" value="/WEB-INF/inc/admin_menu.jsp"></put-attribute>
<put-attribute name="content" value="/WEB-INF/views/admin/{1}.jsp"></put-attribute>
</definition>
</tiles-definitions>
재사용성을 고려한 경우 2
<?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="test" template="/WEB-INF/views/test.jsp">
<!-- 조각 페이지(attribute) 선언 -->
<put-attribute name="main_menu" value="/WEB-INF/inc/main_menu.jsp"></put-attribute>
</definition>
<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>
<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>
</tiles-definitions>
<tiles-definitions> 태그는 최소 하나의 <definition> 태그가 필요하며, definition의 template 속성에 JSP명을 적어서 어디로 이동해야 하는지 알려준다.
Tiles에서는 컨트롤러의 반환값(문자열)이 definition의 이름을 뜻한다. definition이 기존에 하던 작업의 상당수를 효과적으로 할 수 있도록 도와준다.
definition을 먼저 부르고 나중에 JSP를 부르는 방식으로 컨트롤러가 JSP를 이동하는 방법이 달라지게 되었다.
definition 하나가 눈에 보이는 페이지 하나를 뜻한다고 보면 된다. 그러나 이를 페이지 한 장마다 definition을 하나 만들지 않고, layout 폴더를 만들어서 한 번에 관리한다.
주 업무 들어가는 부분만 다르고 나머지는 똑같기 때문에 레이아웃 페이지를 통합하는 과정을 거친다. 주 업무를 따로 빼기 때문에 부분을 재사용하는 게 아니라 통째로 재사용한다고 보면 된다.
이때 index definition을 지워서는 안 된다. 호출하는 JSP의 구성 자체가 다르게 생겼기 때문이다. 외형상 보이는 틀이 다르면 definition도 새로 만든다.
definition의 수는 2~3개, 많아야 4~5개 정도가 적당하다. 그 이상으로 definition이 많으면 화면이 계속 바뀌기 때문에 사용자가 복잡하다는 느낌을 받는다.
중괄호 1
{1}이 넘어온 단어를 이곳에 반환시키라는 의미로 사용된다.
이제 history를 호출하면 * 와일드카드로 받아서 history를 content로 받는다.
조각 페이지(attribute) 선언
value라는 속성에 집어넣을 실제 조각 페이지의 url을 적는다.
definition의 templatefmf 레이아웃 페이지라고 부른다.
<tiles:insertAttribute name="main_menu" />
이제 위 태그를 작성하는 것으로 main_menu를 가져올 수 있다.
파일 생성
com.test.controller
- TestController.java
- MainController.java
- AdminController.java
- MemberController.java
WEB-INF
- tiles.xml
views
- test.jsp
- layout
- index.jsp
- member.jsp (X)
- admin.jsp (X)
- layout.jsp
- member
- info.jsp
- history.jsp
- favorite.jsp
- admin
- log.jsp
- setting.jsp
inc
- main_menu.jsp
- member_menu.jsp
- admin_menu.jsp
- asset.jsp
전체 코드
servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- 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" />
</beans:bean>
<context:component-scan base-package="com.test.nontiles" />
<context:component-scan base-package="com.test.controller" />
</beans:beans>
com.test.controller를 추가해 주었다.
TestController.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 TestController {
@GetMapping(value = "/test.do")
public String test(Model model) {
//http://localhost:8090/tiles/test.do
return "test"; //JSP명(X) definition명(O)
}
}
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 {
@GetMapping(value = "/index.do")
public String index(Model model) {
//tils.xml의 <definition> name값
return "index";
}
}
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 {
@GetMapping(value = "/info.do")
public String info(Model model) {
//return "info"; //<definition name="*">
return "member.info"; //<definition name="*.*">
}
@GetMapping(value = "/history.do")
public String history(Model model) {
//return "history";
return "member.history";
}
@GetMapping(value = "/favorite.do")
public String favorite(Model model) {
//return "favorite";
return "member.favorite";
}
}
두 개의 단어를 따로 받아오도록 return을 변경하였다.
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 {
@GetMapping(value = "/log.do")
public String log(Model model) {
return "admin.log";
}
@GetMapping(value = "/setting.do")
public String setting(Model model) {
return "admin.setting";
}
}
test.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>Test</title>
<link rel="stylesheet" href="https://me2.do/5BvBFJ57">
<style>
</style>
</head>
<body>
<!-- test.jsp -->
<!-- 메인 메뉴 불러오기 -->
<tiles:insertAttribute name="main_menu"></tiles:insertAttribute>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script>
</script>
</body>
</html>
기존에 사용하던 ViewResolver를 삭제했는데, 이게 JSP 페이지명을 찾는 것이기 때문에 이를 지우면 더 이상 return 하는 게 JSP가 아니게 된다.
이를 알아듣기 쉽게 TilesViewResolver라고 임시로 부르도록 하자. TilesViewResolver를 추가하면 JSP명이 아니라 definition명이 된다.
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" />
<style>
</style>
</head>
<body>
<!-- layout > index.jsp -->
<tiles:insertAttribute name="main_menu" />
<main>
<h1>시작 페이지</h1>
</main>
<script>
</script>
</body>
</html>
member.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" />
<style>
</style>
</head>
<body>
<!-- layout > member.jsp -->
<tiles:insertAttribute name="main_menu" />
<tiles:insertAttribute name="member_menu" />
<tiles:insertAttribute name="content" />
<script>
</script>
</body>
</html>
admin.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" />
<style>
pre {
padding: 1rem;
}
</style>
</head>
<body>
<!-- layout > admin.jsp -->
<tiles:insertAttribute name="main_menu" />
<tiles:insertAttribute name="member_menu" />
<tiles:insertAttribute name="content" />
<script>
</script>
</body>
</html>
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" />
<style>
</style>
</head>
<body>
<!-- layout > layout.jsp -->
<tiles:insertAttribute name="main_menu" />
<tiles:insertAttribute name="sub_menu" />
<tiles:insertAttribute name="content" />
<script>
</script>
</body>
</html>
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" %>
<!-- member > info.jsp -->
<main>
<h1>회원 <small>회원정보</small></h1>
<div class="message" title="Isaac">
일반 회원입니다.
</div>
</main>
주 업무 빼고는 모두 지워버렸다.
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" %>
<!-- member > history.jsp -->
<main>
<h1>회원 <small>활동내역</small></h1>
<div class="list">
<div>10:00:00 프로젝트 생성</div>
</div>
</main>
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" %>
<!-- member > favorite.jsp -->
<main>
<h1>회원 <small>즐겨찾기</small></h1>
<div class="list">
<div><a href="#">구글</a></div>
<div><a href="#">아마존</a></div>
<div><a href="#">깃헙</a></div>
</div>
</main>
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" %>
<!-- admin > log.jsp -->
<main>
<h1>관리자 <small>로그</small></h1>
<pre style="padding: 1rem;">
11월 27, 2023 10:09:56 오전 org.apache.coyote.AbstractProtocol start
INFO: 프로토콜 핸들러 ["http-nio-8090"]을(를) 시작합니다.
11월 27, 2023 10:09:56 오전 org.apache.catalina.startup.Catalina start
INFO: 서버가 [6708] 밀리초 내에 시작되었습니다.
</pre>
</main>
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" %>
<!-- admin > setting.jsp -->
<main>
<h1>관리자 <small>환경설정</small></h1>
<div>
<button class="setting">권한 설정하기</button>
</div>
</main>
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" %>
<!-- inc > main_menu -->
<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"%>
<!-- inc > member_menu.jsp -->
<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"%>
<!-- inc > admin_menu -->
<ul>
<li><a href="/tiles/admin/log.do">로그</a></li>
<li><a href="/tiles/admin/setting.do">환경설정</a></li>
</ul>
asset.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<title>NonTilesTest</title>
<!-- asset.jsp -->
<link rel="stylesheet" href="https://me2.do/5BvBFJ57">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>