열심히 끝까지
디바이스 융합 자바(Java) day68 - Spring에서의 MVC2 패턴 본문
디바이스 융합 자바(Java) day68 - Spring에서의 MVC2 패턴
노유림 2022. 9. 19. 17:44[ MVC 패턴의 변화 ]
.jsp 작업을 할 때, ...
1) main.jsp
<%
if(요청 메서드가 POST일 때) {
vo에 사용자가 form에 작성한 데이터를 매핑해서 setter 하는 코드;
}
DB와 연동할 수 있는 코드;
%>
<form>
</form>
2) main.jsp + ctrl.jsp
<form action="ctrl.jsp?action=insert">
</form>
---------------------------
<jsp:useBean vo>
<jsp:setProperty vo>
<%
if(요청한 기능이 ㅁㅁㅁ일 때) {
vo에 사용자가 form에 작성한 데이터를 매핑해서 setter 하는 코드;
DB와 연동할 수 있는 코드;
}
%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:useBean id=""/>
<jsp:setProperty property="" name=""/>
<!-- 2번과 비슷 -->
<%
String mid=request.getParameter("mid");
String mpw=request.getParameter("mpw");
MemberDAO mDAO = new MemberDAO();
if(action.equals("login")){
mvo = mDAO.selectOne(mvo);
if(mvo==null){
이전 페이지;
}
else{
메인페이지
}
}
%>
>> 회사에서 1, 2번으로 하고 있는 회사는 거의 없음
3) main.jsp + Frontcontroller.java(서블릿) => MVC2 패턴 적용
<form action="insert.do">
</form>
---------------------------
서블릿 컨테이너(==톰캣,웹서버)에게 *.do 요청에 대해서
FrontController 서블릿으로 올 수 있도록 매핑 설정을 해줘야 함
-> web.xml
=> @webServlet("*.do")
>> com.ryo.biz.common에 ctrl 작성하지만
파악하기 위해 새로 package 생성
4) MVC2의 과정을 Spring 스타일로 직접 제작해보자!!!!
FrontController 역할을 하는 서블릿을 DispatcherServlet이라고 함
DS(DispatchServlet)는 Action 역할을 수행하는 Controller 들을 호출해서 사용자의 요청을 처리함
DS는 자신이 직접 C들을 하지 않고 HandlerMapping을 통해서 호출함
C는 수행의 결과로 다음 View의 경로(String)를 반환(ActionForward 반환)하는데,
이 경로 정보는 ViewResolver(어떻게 가야하는지를 잘 처리해줄 수 있는 객체 == boolean)에게 전달되어
사용자에게 view 화면(String)을 제공해줌
// 기존에는 actionForwardExecute였는데 어떻게가 반환 되기 때문에 String만 반환하면 된다!!!
// ViewResolver가 .jsp를 추가하기 때문에 생략해서 반환
>> Servlet에 @(어노테이션)이 없는데..?
: web.xml에 존재(src>main>webapp>WEB-INF>web.xml)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>com.ryo.biz.controller.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
>> 다음 항목은 삭제할 것(servlet-name 위에 있었음)
<description></description>
<display-name>DispatcherServlet</display-name>
- 순서 정리
사용자의 요청 --*.do--> DS(DispatcherServlet)(FC 격) -> HM(HandlerMapping) -
-> C호출 -> 경로정보를 반환 -> VR(ViewResolver) -> 사용자에게 화면을 제공
- ViewResolver.java
package com.ryo.biz.controller;
public class ViewResolver {
public String prefix; // ex ) app
// 의존관계 -> DI -> setter 주입
public String suffix; // ex ) .jsp
// 의존관계 -> DI -> setter 주입
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;
}
public String getView(String viewName) {
return prefix+viewName+suffix;
// Spring 프레임워크에서 제공하는 패턴
// 정확한 경로 퉤 하고 뱉음
}
}
- DS(DispatchedServlet).java : FC(FrontController와 같은 역할)
package com.ryo.biz.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class DispatcherServlet
*/
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// 스프링 프레임워크에서 제공하는 방식을 강사님께서 사용
// 의존관계 발생
private HandlerMapping handlerMapping;
private ViewResolver viewResolver;
// init() 메서드를 통해서 DI에 진입
public void init() throws ServletException{
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 {
request.setCharacterEncoding("UTF-8");
doAction(request,response);
}
private void doAction(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String command=request.getRequestURI();
command=command.substring(command.lastIndexOf("/"));
System.out.println(command);
Controller ctrl=handlerMapping.getController(command);
String viewName=ctrl.handleRequest(request, response);
// null은 화면을 호출하지 않음
String view = null;
if(viewName.contains(".do")) {
view=viewName; // 그냥 이동하면 됨
}
else {
view = viewResolver.getView(viewName);
// 추가하여 저장
}
response.sendRedirect(view);
}
}
- HM(Handler Mapping).java
package com.ryo.biz.controller;
import java.util.HashMap;
import java.util.Map;
public class HandlerMapping { // 싱글톤 패턴이 유지됨
// input : 어떤 요청에 대해 == String
// output : 무슨 Controller 객체를 제공해야하는지 == Controller
// 객체의 무분별한 생성을 막기 위해서 == 싱글톤 패턴을 유지하기 위해서 HandlerMapping 사용
private Map<String,Controller> mappings; // 의존관계 -> DI => 생성자 주입
// 만들어지는 시점에
public HandlerMapping() { // 생성자로 new
mappings = new HashMap<String,Controller>();
mappings.put("/login.do", new LoginController()); // 객체만 꺼내서 사진
mappings.put("/main.do", new MainController());
mappings.put("/signin.do", new SigninController());
mappings.put("/board.do", new BoardController());
}
public Controller getController(String command) {
// controller 객체를 반환
return mappings.get(command);
}
}
: 의존관계 존재함 - mappings
mappings에 DI - 생성자 주입
- Controller.interface
package com.ryo.biz.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Controller {
String handleRequest(HttpServletRequest request, HttpServletResponse response);
// 기존에는 actionForwardExecute였는데 어떻게가 반환 되기 때문에 String만 반환하면 된다!!!
}
- LoginController.java(MemberDAO2[jdbc Template 사용])
package com.ryo.biz.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import com.ryo.biz.member.MemberService;
import com.ryo.biz.member.MemberVO;
// import com.ryo.biz.member.impl.MemberDAO;
public class LoginController implements Controller{
@Override
public String handleRequest(HttpServletRequest request, HttpServletResponse response) {
// MemberDAO2를 사용할 시 가져와야할 것
AbstractApplicationContext factory=new GenericXmlApplicationContext("applicationContext.xml");
MemberService ms = (MemberService)factory.getBean("memberService");
String mid=request.getParameter("mid");
String mpw=request.getParameter("mpw");
// MemberDAO mDAO = new MemberDAO(); // MemberDAO 사용 시
MemberVO mVO = new MemberVO();
mVO.setMid(mid);
mVO.setMpw(mpw);
// mVO = mDAO.selectOneMember(mVO); // MemberDAO 사용 시
mVO = ms.selectOneMember(mVO);
factory.close();
if(mVO==null) {
return "login";
// ViewResolver가 .jsp를 추가하기 때문에 생략해서 반환
}
else {
HttpSession session = request.getSession();
session.setAttribute("member", mVO);
return "main.do";
}
}
}
>> 좋아지는 것
※ 메모리를 불필요하게 사용하던 객체들이 현저히 줄어듦
※ 하드코딩이 줄어듦(ㅁㅁㅁ.execute) (코드의 불필요한 반복패턴이 줄어듦) => 코드가 간결해짐
※ 결합도가 엄청 낮아짐 + 응집도가 높아짐 => 유지보수 용이
'디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(수업내용)' 카테고리의 다른 글
디바이스 융합 자바(Java) day69(2) - ModelAndView, ViewResolver 연결 (0) | 2022.09.20 |
---|---|
디바이스 융합 자바(Java) day69(1) - Spring을 DS(Dispatcher Servlet),HM(Handler Mapping),Controller에 대입 (1) | 2022.09.20 |
디바이스 융합 자바(Java) day67(2) - 바인드 변수, Jdbc Template (0) | 2022.09.16 |
디바이스 융합 자바(Java) day67(1) - 바인드 변수, joinPoint (0) | 2022.09.16 |
디바이스 융합 자바(Java) day66(2) - AOP 관련 용어정리 및 예시 (0) | 2022.09.15 |