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 추가
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 다운로드
Attic 선택
attic.apache.org/projects/tiles.html
3.0 선택
튜토리얼 선택
Creating Tiles Pages 선택
tiles.apache.org/framework/tutorial/basic/pages.html
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.*을 해줬기 때문에 컨트롤러에서 리턴 값을 바꿔준다.