초기세팅
pom.xml 추가
지금까지는 계속 MVNREPOSITORY 에서 받았는데,, 이번에는 sonatype 에서 받았다.
둘의 차이점은 없고, 맘에 드는 사이트에서 받아 쓰면 된다.
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-el</artifactId>
<version>3.0.8</version>
</dependency>


application.yml
- prefix와 suffix를 안쓰고 tiles를 이용한다.
server:
port: 9000
spring:
servlet:
multipart:
max-file-size:
10MB
max-request-size:
10MB
devtools:
livereload:
enabled: true
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springframework?serverTimezone=Asia/Seoul
username: 아이디
password: 비밀번호
mybatis:
type-aliases-package: boot.data.*
mapper-locations:
- /mapper/**/*.xml
TilesConfig.java
- SpringBootMybatisTilesApplication 가 있는 package에 java 파일을 생성하여 아래와 같이 입력해준다.
- tilesConfigurer.setDefinitions(new String[] { "/WEB-INF/Tiles.xml" }); 여기 경로만 주의해서 보자.
package boot.last.mini;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
import org.springframework.web.servlet.view.tiles3.SimpleSpringPreparerFactory;
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() {
System.out.println("tiles");
TilesConfigurer tilesConfigurer = new TilesConfigurer();
tilesConfigurer.setDefinitions(new String[] { "/WEB-INF/Tiles.xml" });
tilesConfigurer.setCheckRefresh(true);
tilesConfigurer.setPreparerFactoryClass(SimpleSpringPreparerFactory.class);
return tilesConfigurer;
}
@Bean
public TilesViewResolver tilesViewResolver() {
TilesViewResolver viewResolver = new TilesViewResolver();
viewResolver.setViewClass(TilesView.class);
viewResolver.setOrder(1);
return viewResolver;
}
@Bean
public UrlBasedViewResolver viewResolver() {
final UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setViewClass(TilesView.class);
resolver.setOrder(1);
return resolver;
}
}
Tiles.xml
- 위의 TilesConfig.java 에서 지정해준 경로의 파일이다.
- 여기서 기존 진행했던 Layout에(index) 관련된 사항을 처리한다.
- DOCTYPE도 기입해줘야 한다.

<?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="layout1" template="/WEB-INF/layout/layout1.jsp">
<put-attribute name="title" value="/WEB-INF/layout/title.jsp"/>
<put-attribute name="menu" value="/WEB-INF/layout/menu.jsp"/>
<put-attribute name="main" value="/WEB-INF/layout/main.jsp"/>
<put-attribute name="info" value="/WEB-INF/layout/info.jsp"/>
</definition>
<definition name="/*/*" extends="layout1">
<put-attribute name="main" value="/WEB-INF/{1}/{2}.jsp"/>
</definition>
위의 name에 wildcard형식이 mapping 형식이다.
wildcard를 사용 안하면 위에 주석처리된 부분과 같이 하나하나 일일이 지정해줘야 한다.
wildcard의 /*/* 부분이 value에서 /{1}/{2} 이 된다.
<definition name="layout2" template="/WEB-INF/layout/layout2.jsp">
<put-attribute name="title2" value="/WEB-INF/layout/title2.jsp"/>
<put-attribute name="menu2" value="/WEB-INF/layout/menu2.jsp"/>
<put-attribute name="main" value="/WEB-INF/layout/main.jsp"/>
</definition>
<definition name="/sub/*/*" extends="layout2">
layout 1과 구분해주기 위해서 name을 구분해줘야 한다.
<put-attribute name="main" value="/WEB-INF/{1}/{2}.jsp"/>
</definition>
</tiles-definitions>
SpringBootMybatisTilesApplication
- Tiles 사용을 위해 Tiles config 설정을 하는 boot.last.mini 또한 @ComponentScan 해줘야 한다.
package boot.last.mini;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan("boot.data.*")
@ComponentScan("boot.last.mini")
@MapperScan("boot.data.mapper")
public class SpringBootMybatisTilesApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootMybatisTilesApplication.class, args);
}
}
출력(jsp) 만들기
layout1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link
href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap"
rel="stylesheet">
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"
rel="stylesheet">
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
<style type="text/css">
div.layout div {
}
div.layout div.title {
position: absolute;
top: 10px;
left: 450px;
height: 100px;
}
div.layout div.menu {
position: absolute;
top: 150px;
left: 250px;
height: 100px;
width: 1000px;
}
div.layout div.info {
position: absolute;
top: 250px;
left: 50px;
height: 100px;
font-family: 'Dongle';
font-size: 17px;
width: 200px;
}
div.layout div.main {
position: absolute;
top: 300px;
left: 300px;
height: 500px;
font-family: 'Dongle';
font-size: 17px;
width: 1000px;
}
</style>
</head>
<body>
<div class="layout">
<div class="title">
<tiles:insertAttribute name="title" />
</div>
<div class="menu">
<tiles:insertAttribute name="menu" />
</div>
<div class="info">
<tiles:insertAttribute name="info" />
</div>
<div class="main">
<tiles:insertAttribute name="main" />
</div>
</div>
</body>
</html>
layout2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
<style type="text/css">
div.layout div{
}
div.layout div.title{
position: absolute;
top: 10px;
left: 450px;
height: 100px;
}
div.layout div.menu{
position: absolute;
top: 150px;
left: 250px;
height: 100px;
width: 1000px;
}
div.layout div.main{
position: absolute;
top: 300px;
left: 300px;
height: 500px;
font-family: 'Dongle';
font-size: 17px;
width: 1000px;
}
</style>
</head>
<body>
<div class="layout">
<div class="title">
<tiles:insertAttribute name="title2"/>
</div>
<div class="menu">
<tiles:insertAttribute name="menu2"/>
</div>
<div class="main">
<tiles:insertAttribute name="main"/>
</div>
</div>
</body>
</html>
main.jsp
- <c:set var="root" value="<%=request.getContextPath() %>"></c:set> 를 이용하여 절대경로 사용 가능.. ${root}로 사용한다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<c:set var="root" value="<%=request.getContextPath() %>"></c:set>
<body>
<img alt="" src="${root }/image/m1.jpg" width="500"><br>
<img alt="" src="${root }/image/m2.jpg" width="500"><br>
<img alt="" src="${root }/image/m3.jpg" width="500"><br>
<img alt="" src="${root }/image/m4.jpg" width="500"><br>
<h2>Main Page 입니다</h2>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
<style type="text/css">
ul.menu{
list-style: none;
}
ul.menu li{
width: 100px;
float: left;
border-radius: 30px;
height: 60px;
line-height: 60px;
text-align: center;
margin-right: 10px;
font-size: 24px;
font-family: 'Dongle';
background-color: #f7323f;
cursor: pointer;
}
ul.menu li a{
text-decoration: none;
color: white;
}
</style>
</head>
<c:set var="root" value="<%=request.getContextPath() %>"></c:set>
<body>
<ul class="menu">
<li>
<a href="/">Home</a>
</li>
<li>
<a href="${root }/smart/list">스마트샵</a>
</li>
<li>
<a href="${root }/ipgo/list">상품목록</a>
</li>
<li>
<a href="${root }/reboard/list">답변형게시판</a>
</li>
<li>
<a href="${root }/member/list">회원목록</a>
</li>
<li>
<a href="${root }/member/myinfo">나의정보</a>
</li>
<li>
<a href="/memboard/list">회원게시판</a>
</li>
<li>
<a href="/load/map">오시는길</a>
</li>
</ul>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
<style type="text/css">
ul.menu{
list-style: none;
}
ul.menu li{
width: 100px;
float: left;
border-radius: 30px;
height: 60px;
line-height: 60px;
text-align: center;
margin-right: 10px;
font-size: 24px;
font-family: 'Dongle';
background-color: #FFD73C;
cursor: pointer;
}
ul.menu li a{
text-decoration: none;
color: white;
}
</style>
</head>
<c:set var="root" value="<%=request.getContextPath() %>"></c:set>
<body>
<ul class="menu">
<li>
<a href="/">Home</a>
</li>
<li>
<a href="${root }/smart/list">스마트샵</a>
</li>
<li>
<a href="${root }/ipgo/list">상품목록</a>
</li>
<li>
<a href="${root }/reboard/list">답변형게시판</a>
</li>
<li>
<a href="${root }/member/list">회원목록</a>
</li>
<li>
<a href="${root }/member/myinfo">나의정보</a>
</li>
<li>
<a href="/memboard/list">회원게시판</a>
</li>
<li>
<a href="/load/map">오시는길</a>
</li>
</ul>
</body>
</html>
title.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<title>Insert title here</title>
<script type="text/javascript">
$(function(){
$("#btnloginok").click(function(){
var id=$("#loginid").val();
var pass=$("#loginpass").val();
var root='${root}';
console.log("root"+root);
$.ajax({
type:"get",
url:"/member/login",
dataType:"json",
data:{"id":id,"pass":pass},
success:function(res){
if(res.result=='fail'){
alert("아이디와 비밀번호를 확인해주세요.");
} else {
location.reload();
}
}
});
});
$("#btnlogout").click(function(){
$.ajax({
type:"get",
url:"/member/logout",
dataType:"html",
success:function(res){
alert("로그아웃 되었습니다.");
location.reload();
}
});
});
});
</script>
</head>
<body>
<div class="d-inline-flex">
<c:set var="root" value="<%=request.getContextPath() %>"></c:set>
<a href="/"><img alt="" src="${root }/image/titlett.jpg" width="200"></a>
<c:if test="${sessionScope.loginok==null }">
<button type="button" class="btn btn-outline-danger" onclick="location.href='${root}/login/form'">Login</button>
</c:if>
<c:if test="${sessionScope.loginok!=null }">
<b>${sessionScope.myid }님 좋은하루 보내세요~</b>
<button type="button" class="btn btn-outline-danger" onclick="location.href='${root}/login/logoutprocess'">Logout</button>
</c:if>
<div class="container">
<c:if test="${sessionScope.loginok==null }">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#myModal" id="btnlogin">
Login
</button>
</c:if>
<c:if test="${sessionScope.loginok!=null }">
<button type="button" class="btn btn-danger" id="btnlogout">
Logout
</button>
</c:if>
</div>
<div class="modal" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4>Login</h4>
</div>
<div class="modal-body">
<div class="mb-3 mt-3">
<label for="loginid">id:</label>
<input type="text" class="form-control" id="loginid" placeholder="아이디 입력" style="width: 300px;">
</div>
<div class="mb-3">
<label for="loginpass" class="form-label">Password:</label>
<input type="password" class="form-control" id="loginpass" placeholder="비밀번호 입력" style="width: 300px;">
</div>
</div>
<div class="modal-footer">
<div class="form-check mb-3">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" name="remember">Remember me
</label>
</div>
<button type="button" class="btn btn-outline-primary" data-bs-dismiss="modal" id="btnloginok">Login</button>
<button type="button" class="btn btn-outline-danger" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
title2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<c:set var="root" value="<%=request.getContextPath() %>"></c:set>
<a href="/"><img alt="" src="${root }/image/hello.jpg" width="200"></a><br>
<b>SpringBoot+Mybatis+Tiles</b>
</body>
</html>
IpcoController.java
@Controller
public class IpgoController {
@Autowired
IpgoMapperInter mapper;
@GetMapping("/")
public String start() {
return "/layout/main";
}
@GetMapping("/ipgo/list")
public ModelAndView list() {
ModelAndView model=new ModelAndView();
int totalCount=mapper.getTotalCount();
List<IpgoDto> list=mapper.getAllIpgos();
model.addObject("totalCount", totalCount);
model.addObject("list", list);
model.setViewName("/ipgo/ipgolist");
return model;
}
@GetMapping("/ipgo/ipgoform")
public String form() {
return "/ipgo/ipgoform";
}
결과
main page 접속 -> 상품목록 클릭 시

상품추가 클릭 시

-> mapping 주소에 따라 미리 만들어놓은 layout1 과 loyout2가 각각 적용된다.