아래의 설정 정보는 아래 포스팅을 참고하세요!
- Maven pom 설정 - pom.xml
- DD 설정 - web.xml
Tiles 설정
처음 설정에서 상속받아 동적으로 수정할 수 있다.
<definition name="*.tiles"> : *는 문자열을 의미
{1} : 첫번째 *에 해당하는 문자열을 의미
* Controller에서 viewName을 main2.tiles로 반환하면,
위 설정에 의해 main2.jsp가 레이아웃의 메인 영역에 보여진다.
디렉토리 내에 있는 jsp파일 호출 시
<definition name="*/*.tiles">
{1} : 첫번째 *, 디렉토리 명
{2} : 두번째 *, 파일명
* 컨트롤러에서 member/findbyid-form.tiles라는 viewName을 적용하면 위 설정이 적용된다.
/WEB_INF/tiles-config.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>
<!--
Controller 에서 반환하는 viewName 이
home.tiles 이면 아래의 설정이 적용되어
include 된 화면으로 응답된다
-->
<definition name="home.tiles" template="/WEB-INF/views/templates/layout.jsp">
<put-attribute name="title" value="kosta"/>
<put-attribute name="header" value="/WEB-INF/views/templates/header.jsp"/>
<put-attribute name="left" value="/WEB-INF/views/templates/left.jsp"/>
<put-attribute name="right" value="/WEB-INF/views/templates/right.jsp"/>
<put-attribute name="footer" value="/WEB-INF/views/templates/footer.jsp"/>
<put-attribute name="main" value="/WEB-INF/views/home.jsp"/>
</definition>
<!-- *.tiles인 viewName입력 시, home.tiles를 상속받아 적용한다
template의 path를 동적으로 수정할 수 있다.
<definition name="*.tiles"> : *는 문자열을 의미
{1} : 첫번째 *에 해당하는 문자열을 의미
-->
<definition name="*.tiles" extends="home.tiles">
<put-attribute name="title" value="{1}"/>
<put-attribute name="main" value="/WEB-INF/views/{1}.jsp"/>
</definition>
</tiles-definitions>
Spring configure 설정
/WEB_INF/spring-model.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
<!-- 어노테이션 설정 빈 생성 -->
<context:component-scan base-package="org.kosta"/>
<!-- dbcp -->
<bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:xe"/>
<property name="username" value="scott"/>
<property name="password" value="tiger"/>
</bean>
<!-- Spring과 MyBatis 연동설정
dbcp 를 할당
MyBatis Mapper xml (sql 정의한 파일) 의 위치를 할당
vo or dto 자동으로 별칭이 정해지도록 설정 (소문자로 시작하는 클래스명)
underscore 와 camelCase 즉
컬럼명과 인스턴스변수명이 자동 매핑되도록 설정
ex) product_id 와 productId 가 동일하도록 인식시킨다.
아래의 base-package 는 @Mapper 어노테이션이 명시된
인터페이스의 구현체(DAOImpl)를 생성하기 위한 설정
-->
<mybatis-spring:scan base-package="org.kosta.springmvc13.model.mapper"/>
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dbcp"/>
<!-- <property name="mapperLocations" value="classpath:/mybatis/config/*.xml"/> -->
<property name="typeAliasesPackage" value="org.kosta.springmvc13.model"/>
<property name="configuration">
<bean class="org.apache.ibatis.session.Configuration">
<property name="mapUnderscoreToCamelCase" value="true"/>
</bean>
</property>
</bean>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSessionFactoryBean"/>
</bean>
<!-- 트랜잭션 설정 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dbcp"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>=
/WEB_INF/spring-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<!-- <일반 JSP 반환>
어노테이션 기반 springmvc 설정 -->
<mvc:annotation-driven/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="1"/> <!-- 서블릿 호출 순서 -->
</bean>
<!-- <tiles 적용 JSP 반환>
TilesViewResolver 설정
: 일반 JSP 응답이 아니라 Tiles Layout이 적용된 화면으로 응답하기 위해 설정
-->
<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
<property name="order" value="0"/> <!-- 서블릿 호출 순서 : tiles적용 jsp를 먼저 탐색-->
</bean>
<!-- Tiles Framework 설정
: spring framework에서 Tiles Config xml 을 로딩하기 위한 설정
-->
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles-*.xml</value>
</list>
</property>
</bean>
</beans>
/src/main/webapp/WEB-INF/views
View
/home.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Spring + Tiles Framework
/main2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<h3>메인 2</h3>
/main3.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<h3>메인 3</h3>
/noneTiles.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>noneTiles</title>
</head>
<body>
Tiles 적용 안된 페이지
</body>
</html>
/board
/layout.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%-- tiles framework 선언부 --%>
<%@taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- title이 null인 경우는 무시된다 -->
<title>
<tiles:insertAttribute name="title" ignore="true" />
</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css"
href="${pageContext.request.contextPath}/resources/css/home2.css" >
</head>
<body>
<div id="header">
<!-- Tiles header 영역 -->
<tiles:insertAttribute name="header"/>
</div>
<div class="container-fluid text-center">
<div class="row content">
<div id="left" class="col-sm-3 sidenav" >
<!-- Tiles left 영역 -->
<tiles:insertAttribute name="left"/>
</div>
<div id="main" class="col-sm-7 text-left">
<!-- Tiles main 영역 -->
<tiles:insertAttribute name="main"/>
</div>
<div id="right" class="col-sm-2 sidenav">
<!-- Tiles right 영역 -->
<tiles:insertAttribute name="right"/>
</div>
</div>
</div>
<div id="footer">
<!-- Tiles footer 영역 -->
<tiles:insertAttribute name="footer" />
</div>
</body>
</html>
/header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Logo</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li class="active"><a href="${pageContext.request.contextPath }/home.do">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Projects</a></li>
<li><a href="#">Contact</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="#"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
</ul>
</div>
</div>
</nav>
/right.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<div class="well">
<p>ADS</p>
</div>
<div class="well">
<p>ADS</p>
</div>
/left.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<a href="${pageContext.request.contextPath}/main2.do">두번째 메인 보기</a><br>
<a href="${pageContext.request.contextPath}/main3.do">세번째 메인 보기</a><br>
<a href="${pageContext.request.contextPath}/noneTiles.do">Tiles 적용안되는 jsp 보기</a><br>
<a href="${pageContext.request.contextPath}/findbyid-form.do">회원검색</a>
<br>
<%-- 주소로 회원검색 폼 링크 --%>
<a href="${pageContext.request.contextPath}/findbyaddress-form.do">
주소로 회원검색
</a>
/footer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<footer class="container-fluid text-center">
<p>Footer Text</p>
</footer>
/member
/findbyid-form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<form action="${pageContext.request.contextPath}/findMemberById.do">
아이디 <input type="text" name="id">
<input type="submit" value="검색">
</form>
/findbyid-result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
검색결과 ${memberVO}
/findbyaddress-form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<form action="${pageContext.request.contextPath}/findMemberByAddress.do">
<select name="address" required="required">
<option value="">-주소-</option>
<c:forEach items="${addressList}" var="address">
<option value="${address}">${address}</option>
</c:forEach>
</select>
<input type="submit" value="검색">
</form>
/findbyaddress-result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
${param.address}에 사는 회원명단 <br><br>
<c:forEach items="${memberList}" var="member">
${member.id} ${member.name}<br>
</c:forEach>
/src/main/webapp/resources/css
/board2.css
/* Remove the navbar's default margin-bottom and rounded borders */
.navbar {
margin-bottom: 0;
border-radius: 0;
}
/* Set height of the grid so .sidenav can be 100% (adjust as needed) */
.row.content {
height: 450px;
}
#main{
padding: 20px;
}
/* Set gray background color and 100% height */
.sidenav {
padding-top: 20px;
background-color: #f1f1f1;
height: 100%;
}
/* Set black background color, white text and some padding */
footer {
background-color: #555;
color: white;
padding: 15px;
}
/* On small screens, set height to 'auto' for sidenav and grid */
@media screen and (max-width: 767px) {
.sidenav {
height: auto;
padding: 15px;
}
.row.content {height:auto;}
}
MyBatis 설정 (Proxy)
/src/main/resource/org.kosta.springmvc13.model.mapper
/MemberMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Sql Mapper -->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.kosta.springmvc13.model.mapper.MemberMapper">
<sql id="selectMember">
select id,password,name,address
from spring_member
</sql>
<select id="findMemberById" resultType="memberVO">
<include refid="selectMember"/>
where id=#{value}
</select>
<select id="getMemberAddressKind" resultType="string">
select distinct address from spring_member
</select>
<select id="findMemberByAddress" resultType="memberVO">
<include refid="selectMember"/>
where address=#{value}
</select>
</mapper>
src/main/java/org.kosta.springmvc13.model.mapper
/MemberMapper.java<<interface>>
package org.kosta.springmvc13.model.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.kosta.springmvc13.model.MemberVO;
@Mapper
public interface MemberMapper {
public MemberVO findMemberById(String id);
public List<String> getMemberAddressKind();
public List<MemberVO> findMemberByAddress(String address);
}
Model
/src/main/java/org.kosta.myproject.model.vo
/MemberVO.java
package org.kosta.springmvc11.model.vo;
public class MemberVO {
private String id;
private String password;
private String name;
private String address;
public MemberVO() {
super();
}
public MemberVO(String id, String password, String name, String address) {
super();
this.id = id;
this.password = password;
this.name = name;
this.address = address;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "MemberVO [id=" + id + ", password=" + password + ", name="
+ name + ", address=" + address + "]";
}
}
Controller
/src/main/java/org.kosta.myproject.controller
/HomeController.java
package org.kosta.springmvc13.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HomeController {
@RequestMapping("home.do")
public String home() {
// tiles-config.xml 에 설정한 definition name인
// home.tiles 를 viewName으로 반환하여
// tiles 적용 화면으로 응답하게 한다
return "home.tiles";
}
@RequestMapping("main2.do")
public String main2() {
return "main2.tiles";
}
@RequestMapping("main3.do")
public String main3() {
return "main3.tiles";
}
@RequestMapping("noneTiles.do")
public String noneTiles() {
//viewResolver에서 .tile가 아니므로, 일반 jsp를 찾음
return "noneTiles";
}
}
/MemberController.java
package org.kosta.springmvc13.controller;
import java.util.List;
import javax.annotation.Resource;
import org.kosta.springmvc13.model.MemberVO;
import org.kosta.springmvc13.model.mapper.MemberMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class MemberController {
@Resource
private MemberMapper memberMapper;
// 아이디로 회원검색
@RequestMapping("findbyid-form.do")
public String findMemberByIdForm() {
return "member/findbyid-form.tiles";
}
@RequestMapping("findMemberById.do")
public ModelAndView findMemberById(String id) {
MemberVO memberVO = memberMapper.findMemberById(id);
return new ModelAndView("member/findbyid-result.tiles",
"memberVO", memberVO);
}
// 주소로 회원검색
@RequestMapping("findbyaddress-form.do")
public ModelAndView findByAddressForm() {
List<String> addressList
= memberMapper.getMemberAddressKind();
return new ModelAndView("member/findbyaddress-form.tiles",
"addressList", addressList);
}
@RequestMapping("findMemberByAddress.do")
public String findByAddress(String address, Model model) {
model.addAttribute("memberList", memberMapper.findMemberByAddress(address));
return "member/findbyaddress-result.tiles";
}
}
Test - 단위 테스트
/src/test/java/org.kosta.springmvc17
/MemberUnit.java
package org.kosta.springmvc17;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.kosta.springmvc13.model.mapper.MemberMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= {"file:src/main/webapp/WEB-INF/spring-model.xml"})
public class MemberUnit {
@Autowired
private MemberMapper memberMapper;
@Test
public void test() {
/*String id="java";
System.out.println(memberMapper.findMemberById(id));*/
/*System.out.println(memberMapper.getMemberAddressKind());*/
String address="판교";
System.out.println(memberMapper.findMemberByAddress(address));
}
}
[ Browser 결과 화면 ]
1. home 화면 (url이 동적으로 생성되어 home.do로 뜬다)
2. '두번째 메인 보기' 클릭 (tiles-config.xml에서 설정하였으므로, url이 동적으로 생성되어 main2.do로 뜬다)
3. '세번째 메인 보기' 클릭 (url이 동적으로 생성되어 main3.do로 뜬다)
4. 'Tiles 적용안되는 jsp 보기' 클릭
5. '회원검색' 클릭
6. 아이디 입력 후, 회원 검색 결과 조회 (main 영역에 findbyid-result.jsp 결과가 뜬다)
7. '주소로 회원검색' 클릭
8. 주소 입력 후, 회원 검색 결과 조회