특징
- 모델 2 아키텍쳐 지원
- 스프링과 다른 모듈과의 연계 쉬움
- 타일즈나 사이트메시 같은 view 기술과 연계가 쉬움
- 태그 라이브러리를 통해 message 출력, theme 적용 그리고 입력 폼을 보다 쉽게 구현할 수 있음
SimpleUrlController 이용한 MVC 실습
web.xml
- 브라우저에서 *.do로 요청하면 스프링의 디스패쳐서블릿 클래스가 요청 받을 수 있게 서블릿 매핑
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
action-servlet
- 스프링에서 필요한 빈들을 설정
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- id가 simpleUrlController인 빈 생성 -->
<bean id="simpleUrlController" class="com.spring.ex01.SimpleUrlController"/>
<!-- SimpleUrlHandlerMapping를 이용해 /test/index.do로 요청 시 simpleUrlController를 호출하도록 매핑 -->
<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/test/index.do">simpleUrlController</prop>
</props>
</property>
</bean>
</beans>
SimpleUrlController.java
- 매핑된 요청에 대해 컨트롤러의 기능 수행
public class SimpleUrlController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
//작업을 마친 후 뷰 이름을 ModelAndView에 index.jsp로 설정하여 반환
return new ModelAndView("index.jsp");
}
}
index.jsp
- 요청에 대해 컨트롤러가 브라우저로 전송하는 JSP
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<h1>index.jsp</h1>
</body>
</html>
MultiActionController 이요해 스프링 MVC 실습
SimpleUrlController를 이용해 요청을 처리하려면 각 요청명에 대해 다시 스프링의 Controller 인터페이스를 구현한 각각의 컨트롤러를 만들어야 하지만 MultiActionController를 이용하면 여러 요청명에 대해 한 개의 컨트롤러에 구현된 각 메서드로 처리할 수 있음
web.xml
- 브라우저에서 *.do로 요청하면 스프링의 디스패쳐서블릿 클래스가 요청 받을 수 있게 서블릿 매핑
action-servlet
- 스프링에서 필요한 빈들을 설정
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!--
컨트롤러에서 모델앤뷰 인자로 뷰 이름이 반환되면 InternalResourceViewResolver의 프로퍼티
prefix 속성에 지정된 /test 폴더에서 모델앤뷰 인자로 넘어온 뷰 이름에 해당되는 jsp를 선택해
디스패쳐서블릿으로 보냄
-->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/test/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="userUrlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<!-- url 요청명이 /test/*.do로 시작되면 userController 호출 -->
<prop key="/test/*.do">userController</prop>
</props>
</property>
</bean>
<!-- methodNameResolver 프로퍼티에 userMethodNameResolver를 주입해 지정한 요청명에 대해 직접 메서드 호출 -->
<bean id="userController" class="com.spring.ex02.UserController">
<property name="methodNameResolver">
<ref local="userMethodNameResolver" />
</property>
</bean>
<!-- PropertiesMethodNameResolver를 이용해 /test/login.do로 요청하면 userController의 login 메서드 호출 -->
<bean id="userMethodNameResolver"
class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<prop key="/test/login.do">login</prop>
<prop key="/test/memberInfo.do">memberInfo</prop>
</props>
</property>
</bean>
</beans>
UserController.java
- 매핑된 요청에 대해 컨트롤러 기능 수행
public class UserController extends MultiActionController{
public ModelAndView login(HttpServletRequest request, HttpServletResponse response) throws Exception{
String userID = "";
String password = "";
ModelAndView mav = new ModelAndView();
request.setCharacterEncoding("utf-8");
userID = request.getParameter("userID");
password = request.getParameter("password");
//로그인 정보 바인딩
mav.addObject("userID", userID);
mav.addObject("password", password);
//포워딩할 jsp 이름 설정
mav.setViewName("result");
return mav;
}
}
loginForm.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<%
request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<form action="${contextPath}/test/login.do" method="post">
<table border="1" width="80%" align="center">
<tr align="center">
<td>아이디</td>
<td>비밀번호</td>
</tr>
<tr align="center">
<td><input type="text" name="userID" size="20"></td>
<td><input type="password" name="password" size="20"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="로그인">
<input type="reset" value="다시입력">
</td>
</tr>
</table>
</form>
</body>
</html>
result.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<%
request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<table border="1" width="50%" align="center">
<tr align="center">
<td>아이디</td>
<td>비밀번호</td>
</tr>
<tr align="center">
<td>${userID}</td>
<td>${password}</td>
</tr>
</table>
</body>
</html>
입력한 값이 그대로 출력
요청명과 동일한 JSP로 표시하기
UserController.java
- URL 요청명에서 .do를 제외한 요청명을 가져오는 getViewName()메서드 추가
- request 객체를 위의 메서드 인자로 전달해 URL 요청명에서 .do를 제외한 뷰 이름 가져옴
(/test/login.do인 경우 login을 가져옴)
- 그리고 setViewName()을 이용해 뷰이름으로 설정하면 /test/login.do로 요청 시 /test/login.jsp로 가게 됨
public class UserController extends MultiActionController{
public ModelAndView login(HttpServletRequest request, HttpServletResponse response) throws Exception{
String userID = "";
String password = "";
String viewName = getViewName(request);
ModelAndView mav = new ModelAndView();
request.setCharacterEncoding("utf-8");
userID = request.getParameter("userID");
password = request.getParameter("password");
//로그인 정보 바인딩
mav.addObject("userID", userID);
mav.addObject("password", password);
//포워딩할 jsp 이름 설정
// mav.setViewName("result");
mav.setViewName(viewName);
return mav;
}
//request 객체에서 URL 요청명을 가져와 .do를 제외한 요청명을 구하는 메서드
private String getViewName(HttpServletRequest request) throws Exception{
String contextPath = request.getContextPath();
String uri = (String) request.getAttribute("javax.servlet.include.request_uri");
if (uri == null || uri.trim().equals("")) {
uri = request.getRequestURI();
}
int begin = 0;
if (!((contextPath==null)||("".equals(contextPath)))) {
begin = contextPath.length();
}
int end;
//uri에서 indexOf안의 기호가 처음 나타나는 곳의 index 번호 리턴, 없을 경우 -1을 리턴
if (uri.indexOf(";")!=-1) {
end = uri.indexOf(";");
}
else if(uri.indexOf("?")!=-1) {
end = uri.indexOf("?");
}else {
end = uri.length();
}
String fileName = uri.substring(begin,end);
if (fileName.indexOf(".")!=-1) {
fileName = fileName.substring(0,fileName.lastIndexOf("."));
}
if (fileName.lastIndexOf("/")!=-1) {
fileName = fileName.substring(fileName.lastIndexOf("/"),fileName.length());
}
return fileName;
}
}
login.jsp
- 위의 result.jsp와 동일