Spring/Spring
day64) Spring-Controller설계1
code_learner
2022. 3. 31. 15:01
Spring에서 제공하는 DispatcherServlet과 스프링 컨테이너를 활용하여 Controller를 설계해보자.
[설계]
NewFile.jsp에서 글을 쓰면 /WEB-INF/NewFile1.jsp(url로 접근할 수 없도록)에서 출력
[View]
NewFile.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>
<form action="next.do" method="post">
<input type="text" name="msg">
<input type="submit" value="다음페이지">
</form>
</body>
</html>
NewFile1.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>
<h1>${msg}</h1>
</body>
</html>
[web.xml]
.do 요청이 오게된다면 필터를 통해 인코딩처리가 되고, Spring에서 제공하는 DispatcherServlet에 Mapping
더보기
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://Java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<filter-name>encFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
DispatcherServlet이 생성되게 된다면 init()메서드가 자동으로 호출되게 되는데 여기서 스프링이 제공하는 HandlerMapping과 ViewResolver를 주입해주어야 한다.
아래코드는 직접 작성해보는 DS, HM, VR(Spring에서 사용하지 않는다)
-DS
더보기
package com.test.app.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.mvc.Controller;
/**
* Servlet implementation class DispatcherServlet
*/
// DS은 FrontController의 역할!
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private HandlerMapping handlerMapping;
private ViewResolver viewResolver;
public void init() {
handlerMapping=new HandlerMapping();
viewResolver=new ViewResolver();
viewResolver.setPrefix("./");
viewResolver.setSuffix(".jsp");
}
/**
* @see HttpServlet#HttpServlet()
*/
public DispatcherServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doAction(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doAction(request, response);
}
private void doAction(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 사용자(브라우저,클라이언트)의 요청을 추출
String uri=request.getRequestURI();
String command=uri.substring(uri.lastIndexOf("/"));
System.out.println(command);
// 2. 요청을 분기처리
// -> HandlerMapping을 통해서 command에 해당하는 Controller객체를 반환
Controller ctrl=handlerMapping.getController(command);
String viewName=ctrl.handleRequest(request, response);
// 1) 싱글톤패턴 유지
// 2) 가독성 향상
if(!viewName.contains(".do")) {
viewName=viewResolver.getView(viewName);
}
response.sendRedirect(viewName);
}
}
-HandlerMapping
더보기
package com.test.app.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.servlet.mvc.Controller;
import com.test.app.controller.board.BoardController;
import com.test.app.controller.board.DeleteBoardController;
import com.test.app.controller.board.InsertBoardController;
import com.test.app.controller.board.MainController;
import com.test.app.controller.board.UpdateBoardController;
import com.test.app.controller.member.LoginController;
import com.test.app.controller.member.LogoutController;
// 어떤 요청처리 로직을 가진 클래스(==Action,Controller)를 반환해야하는지 알려주는 클래스
public class HandlerMapping {
private Map<String,Controller> mappings;
public HandlerMapping() {
mappings=new HashMap<String,Controller>();
mappings.put("/next.do", new NextController());
}
public Controller getController(String path) {
return mappings.get(path);
}
}
-ViewResolver
더보기
package com.test.app.controller;
public class ViewResolver {
private String prefix;
private String suffix;
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
// input: Controller가 어떤 View로 이동해야하는지 반환
// output: 다음 실행될 JSP 경로를 생성
public String getView(String viewName) {
return prefix+viewName+suffix;
}
}
[DispatcherServlet-servlet.xml]
위 코드들을 스프링에서 제공하므로 우리는 처리만 해달라고 DispatcherServlet-servlet.xml파일에 설정만 해주면 스프링컨 테이너가 ViewResolver, HandlerMapping을 주입해주고, 스프링제공 DS가 각각 처리해준다.
더보기
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.xsd">
<!-- DS를 위한 스프링 컨테이너를 위한 설정파일. init()이 자동호출될적에 필요 -->
<!-- DS 생성 -> init() 자동호출 -> DI -> 컨테이너가 하는 일 -> 설정파일(.xml) -> DS-servlet.xml -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
<!-- id를 써줄 것: 1. ~Resolver를 많이 써서 내부적으로 viewResolver를 쓸 수 있도록 설정해둠 -->
<!-- viewResolver를 통해 간다면 WEB-INF 경로도 접근가능해진다 -->
<property name="prefix" value="/WEB-INF/view/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- redirect: 가 붙지 않은 viewName을 보면, DS는 Mav객체에서 M정보를 추출, req객체에서 M정보를 저장해서 JSP포워딩 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/next.do">next</prop>
</props>
</property>
</bean>
<bean class="controller.NextController" id="next"></bean>
</beans>
[NextController.jsp]
Handler매핑으로 수행할 Controller(Action)
더보기
package controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class NextController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
String msg = request.getParameter("msg");
ModelAndView mav = new ModelAndView();
mav.addObject("msg", msg);//가지고갈 정보
mav.setViewName("NewFile1");//보낼 위치
return mav;
}
}