ViewResolver
String타입의 뷰 이름으로부터 실제로 사용할 뷰 객체를 결정해준다.
resourceViewResolver : controller가 리턴한 뷰 이름을 기반으로 Controller처리 결과를 생성할 뷰를 결정
NoticeControllerr.jsp
package com.webstore.web.controller.customer;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller //뷰페이지를 설정하기 위한 컨트롤러
@RequestMapping("/customer/notice/")
public class NoticeController {
@RequestMapping("list") //list, detail, edit, reg, del
public String list(Model model) {
model.addAttribute("test", "Hello Pusan!!");
return "customer/notice/list"; //앞의 경로가 동일한 경우는 앞부분 생략가능함.
} //resourceViewResolver : controller가 리턴한 뷰 이름을 기반으로 Controller처리 결과를 생성할 뷰를 결정
@RequestMapping("detail")
public String detail() {
return "customer/notice/detail";
}
}
컨트롤러에서 뷰(view)

뷰(view)의 구조

DispatcherServlet.class 이 클라이언트의 요청을 처리한다.(모델, 뷰를 받아서)

자동으로 서버가 restart 할 수 있게 만들기 pom.xml 추가
Maven Repository: Search/Browse/Explore
A general programming library in Java/Android. It's easy to learn and simple to use with concise and powerful APIs. Last Release on Feb 18, 2021
mvnrepository.com
Spring Boot DevTools 2.4.2

2.4.2 자동으로 재시작해주는 툴
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.webstore</groupId>
<artifactId>SpringWeb2</artifactId>
<version>1.0</version>
<name>SpringWeb2</name>
<description>WebStore Spring Boot Project</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-jasper -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
관리자 페이지 MVC
관리자 controller 생성

NoticeController.java
package com.webstore.web.controller.admin.board;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller("adminNoticeController")
@RequestMapping("/admin/board/notice/")
public class NoticeController {
@RequestMapping("list")
public String list() {
return "/admin/board/notice/list";
}
@RequestMapping("detail")
public String detail() {
return "/admin/board/notice/detail";
}
@RequestMapping("reg")
public String reg() {
return "/admin/board/notice/reg";
}
}
컨트롤러 이름이 중복되었을때 설정

구조 만들어주기

list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<main>
<h1>공지사항</h1>
</main>
</body>
</html>

타일즈(Tiles) 적용하기 - 전체 레이아웃 잡기
include 보다 개선된 것이 타일즈(Tiles)
공통된 부분을 모듈화
전체 뷰에서 사용할 목적의 inc

admin 내에서 공통적으로 사용하는 inc 만들기

customer 내에서 공통적으로 사용하는 inc 만들기

Tiles 다운로드
Welcome to The Apache Software Foundation!
Reports Official ASF reports and statements, including Quarterly and Annual Reports, Vision Statement, "Apache is Open", 5-Year Strategic Plan, and more.
apache.org
Attic 선택

The Apache Attic - Apache Attic
The Apache Attic was created in November 2008 to provide process and solutions to make it clear when an Apache project has reached its end of life. Specifically to be: "responsible for the oversight of projects which otherwise would not have oversight; and
attic.apache.org

attic.apache.org/projects/tiles.html
Apache Tiles - Apache Attic
Apache Tiles moved into the Attic in December 2018. Apache Tiles™ is a templating framework built to simplify the development of web application user interfaces. The website, downloads and issue tracker all remain open, though the issue tracker is read-o
attic.apache.org

3.0 선택

튜토리얼 선택

Creating Tiles Pages 선택

tiles.apache.org/framework/tutorial/basic/pages.html
Apache Tiles - Framework - Creating Tiles Pages
Creating and using Tiles pages After installing and learning some of Tiles concepts, it is time to create some pages. Here you will find the steps to create reusable Tiles pieces and complete pages. Create a template Let's take the classic layout page stru
tiles.apache.org

WEB-INF에 추가
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="myapp.homepage" template="/layouts/classic.jsp">
<put-attribute name="title" value="Tiles tutorial homepage" />
<put-attribute name="header" value="/tiles/banner.jsp" />
<put-attribute name="menu" value="/tiles/common_menu.jsp" />
<put-attribute name="body" value="/tiles/home_body.jsp" />
<put-attribute name="footer" value="/tiles/credits.jsp" />
</definition>
</tiles-definitions>
라이브러리 추가하기
tiles

jstl

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.webstore</groupId>
<artifactId>SpringWeb2</artifactId>
<version>1.0</version>
<name>SpringWeb2</name>
<description>WebStore Spring Boot Project</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-jasper -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tiles/tiles-jsp -->
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>3.0.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
NoticeController.java
package com.webstore.web.controller.customer;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
//resourceViewResolver : controller가 리턴한 뷰 이름을 기반으로 Controller처리 결과를 생성할 뷰를 결정
@Controller //뷰페이지를 설정하기 위한 컨트롤러
@RequestMapping("/customer/notice/")
public class NoticeController {
@RequestMapping("list") //list, detail, edit, reg, del
public String list(Model model) {
model.addAttribute("test", "Hello gumi!!");
// return "customer/notice/list"; //ResourceViewResolver 앞의 경로가 동일한 경우는 앞부분 생략가능함.
return "customer.notice.list"; //tilesViewResolver
}
@RequestMapping("detail")
public String detail() {
return "customer/notice/detail";
}
}
customer/notice
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지목록 ${test }</title>
</head>
<body>
<main>
<h1>사용자 게시글</h1>
</main>
</body>
</html>
tiles.xml 상황에 맞게 수정
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="customer.notice.list" template="/WEB-INF/view/customer/inc/layout.jsp">
<put-attribute name="title" value="Tiles tutorial homepage" />
<put-attribute name="header" value="/WEB-INF/view/inc/header.jsp" />
<put-attribute name="visual" value="/WEB-INF/view/customer/inc/visual.jsp" />
<put-attribute name="aside" value="/WEB-INF/view/customer/inc/aside.jsp" />
<put-attribute name="main" value="/WEB-INF/view/customer/notice/list.jsp" />
<put-attribute name="footer" value="/WEB-INF/view/inc/footer.jsp" />
</definition>
</tiles-definitions>
타일즈 지시자 만들기
설정된 것을 지시하는 class 생성

@Configuration 이 노테이션 사용 설정 정보 정의
@Bean 객체를 자동으로 생성해준다.
우선순위를 부여할 필요가 있다. tilesViewResolver 우선되게끔 설정
TilesConfig.java
package com.webstore.web.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesView;
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
@Configuration
public class TilesConfig {
@Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer tilesConfigurer = new TilesConfigurer();
tilesConfigurer.setDefinitions(new String[] {"/WEB-INF/tiles.xml"});
tilesConfigurer.setCheckRefresh(true);
return tilesConfigurer;
}
@Bean
public TilesViewResolver tilesViewResolver() {
TilesViewResolver viewResolver = new TilesViewResolver();
viewResolver.setViewClass(TilesView.class);
viewResolver.setOrder(1);
return viewResolver;
}
}
템플릿으로 설정했던 레이아웃 구성하기 - list에 레이아웃 적용

layout.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>사용자게시글 목록 ${test }</title>
</head>
<body>
<!-- header 부분 -->
<tiles:insertAttribute name="header" />
</body>
</html>
view/ins
header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<header>
<div>
<section>
<h1>메인메뉴</h1>
</section>
</div>
</header>
costomer/ins
visual.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<div>
<div>visual</div>
</div>
view/ins
footer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<footer>
<div>
<h2>웹스토어</h2>
<div>
<dl>
<dt>주소 : </dt>
<dd>구미시</dd>
<dt>관리자메일:</dt>
<dd>admin@webstore.com</dd>
</dl>
</div>
<div>
Copyright webstore.com 2021 ALL Right Reserved.
</div>
</div>
</footer>

detail.jsp 레이아웃 적용시키기 - 패턴 적용
tiles를 이용할 경우 jsp가 생길 때마다 xml을 설정해 줘야 하는 번거로움이 있다.
이 경우에는 패턴을 적용해서 공통적으로 적용되게끔 추가해준다.
customer/inc
detail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지목록 ${test }</title>
</head>
<body>
<main>
<h1>사용자 게시글 상세내용</h1>
</main>
</body>
</html>
controller/customer/
NoticeController.java
package com.webstore.web.controller.customer;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
//resourceViewResolver : controller가 리턴한 뷰 이름을 기반으로 Controller처리 결과를 생성할 뷰를 결정
@Controller //뷰페이지를 설정하기 위한 컨트롤러
@RequestMapping("/customer/notice/")
public class NoticeController {
@RequestMapping("list") //list, detail, edit, reg, del
public String list(Model model) {
model.addAttribute("test", "Hello gumi!!");
// return "customer/notice/list"; //ResourceViewResolver 앞의 경로가 동일한 경우는 앞부분 생략가능함.
return "customer.notice.list"; //tilesViewResolver
}
@RequestMapping("detail") //list, detail, edit, reg, del
public String detail() {
return "customer.notice.detail";
}
}
타일즈에 패턴 적용


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="customer.*.*" template="/WEB-INF/view/customer/inc/layout.jsp">
<put-attribute name="title" value="Tiles tutorial homepage" />
<put-attribute name="header" value="/WEB-INF/view/inc/header.jsp" />
<put-attribute name="visual" value="/WEB-INF/view/customer/inc/visual.jsp" />
<put-attribute name="aside" value="/WEB-INF/view/customer/inc/aside.jsp" />
<put-attribute name="main" value="/WEB-INF/view/customer/{1}/{2}.jsp" />
<put-attribute name="footer" value="/WEB-INF/view/inc/footer.jsp" />
</definition>
</tiles-definitions>

관리자 페이지 레이아웃 Tiles 적용
NoticeController.java
package com.webstore.web.controller.admin.board;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller("adminNoticeController")
@RequestMapping("/admin/board/notice/")
public class NoticeController {
@RequestMapping("list")
public String list() {
return "admin.board.notice.list";
}
@RequestMapping("detail")
public String detail() {
return "admin.board.notice.detail";
}
@RequestMapping("reg")
public String reg() {
return "admin.board.notice.reg";
}
}
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<main>
<h1>공지사항</h1>
</main>
</body>
</html>
detail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<main>
<h1>공지사항 상세 글보기</h1>
</main>
</body>
</html>
reg.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<main>
<h1>공지사항 등록</h1>
</main>
</body>
</html>
visual.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<div>
<div>visual-admin</div>
</div>
aside.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<div>
<div>aside-admin</div>
</div>

layout.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>The WebStore</title>
</head>
<body>
<!-- header 부분 -->
<tiles:insertAttribute name="header" />
<!-- visual 부분 -->
<tiles:insertAttribute name="visual" />
<div>
<div>
<!-- aside -->
<tiles:insertAttribute name="aside" />
<!-- main -->
<tiles:insertAttribute name="main" />
</div>
</div>
<!-- footer -->
<tiles:insertAttribute name="footer" />
</body>
</html>
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="customer.*.*" template="/WEB-INF/view/customer/inc/layout.jsp">
<put-attribute name="title" value="Tiles tutorial homepage" />
<put-attribute name="header" value="/WEB-INF/view/inc/header.jsp" />
<put-attribute name="visual" value="/WEB-INF/view/customer/inc/visual.jsp" />
<put-attribute name="aside" value="/WEB-INF/view/customer/inc/aside.jsp" />
<put-attribute name="main" value="/WEB-INF/view/customer/{1}/{2}.jsp" />
<put-attribute name="footer" value="/WEB-INF/view/inc/footer.jsp" />
</definition>
<definition name="admin.*.*.*" template="/WEB-INF/view/admin/inc/layout.jsp">
<put-attribute name="title" value="Tiles tutorial homepage" />
<put-attribute name="header" value="/WEB-INF/view/inc/header.jsp" />
<put-attribute name="visual" value="/WEB-INF/view/admin/inc/visual.jsp" />
<put-attribute name="aside" value="/WEB-INF/view/admin/inc/aside.jsp" />
<put-attribute name="main" value="/WEB-INF/view/admin/{1}/{2}/{3}.jsp" />
<put-attribute name="footer" value="/WEB-INF/view/inc/footer.jsp" />
</definition>
</tiles-definitions>
board/notice/* 을 의미한다.






HomeController 레이아웃 Tiles 적용
tailes.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="customer.*.*" template="/WEB-INF/view/customer/inc/layout.jsp">
<put-attribute name="title" value="Tiles tutorial homepage" />
<put-attribute name="header" value="/WEB-INF/view/inc/header.jsp" />
<put-attribute name="visual" value="/WEB-INF/view/customer/inc/visual.jsp" />
<put-attribute name="aside" value="/WEB-INF/view/customer/inc/aside.jsp" />
<put-attribute name="main" value="/WEB-INF/view/customer/{1}/{2}.jsp" />
<put-attribute name="footer" value="/WEB-INF/view/inc/footer.jsp" />
</definition>
<definition name="admin.*.*.*" template="/WEB-INF/view/admin/inc/layout.jsp">
<put-attribute name="title" value="Tiles tutorial homepage" />
<put-attribute name="header" value="/WEB-INF/view/inc/header.jsp" />
<put-attribute name="visual" value="/WEB-INF/view/admin/inc/visual.jsp" />
<put-attribute name="aside" value="/WEB-INF/view/admin/inc/aside.jsp" />
<put-attribute name="main" value="/WEB-INF/view/admin/{1}/{2}/{3}.jsp" />
<put-attribute name="footer" value="/WEB-INF/view/inc/footer.jsp" />
</definition>
<definition name="home.*" template="/WEB-INF/view/inc/layout.jsp">
<put-attribute name="title" value="Tiles tutorial homepage" />
<put-attribute name="header" value="/WEB-INF/view/inc/header.jsp" />
<put-attribute name="main" value="/WEB-INF/view/{1}.jsp" />
<put-attribute name="footer" value="/WEB-INF/view/inc/footer.jsp" />
</definition>
</tiles-definitions>

layout.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- header 부분 -->
<tiles:insertAttribute name="header" />
<div>
<div>
<!-- main 부분 -->
<tiles:insertAttribute name="main" />
</div>
</div>
<!-- footer 부분 -->
<tiles:insertAttribute name="footer" />
</body>
</html>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<main>
<section>
<h1>Index Page</h1>
</section>
</main>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<main>
<section>
<h1>gumi Page</h1>
</section>
</main>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<main>
<section>
<h1>help Page</h1>
</section>
</main>
HomeController.java
package com.webstore.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HomeController {
@RequestMapping("/index")
public String sampleMethod() {
return "home.index";
}
@RequestMapping("/gumi")
public String sampleMethod2() {
return "home.gumi";
}
@RequestMapping("/help")
public String list() {
return "home.help";
}
}
xml에 home.*을 해줬기 때문에 컨트롤러에서 리턴 값을 바꿔준다.








