코딩하는 문과생
[Web] 2. MVC 패턴 - Controller와 View 본문
[Preview]

- 패턴의 종류: 싱글톤 패턴, MVC패턴...
- jsp와 servlet만 가지고도 만들 수 있다. But, 비효율적
***따라서 servlet은 Controller역할, JSP가 View의 역할을 맡는다.***

[Front Servlet 생성]
요청과 응답만을 담당
package front.ctrl;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class DispatcherServlet
*/
@WebServlet("*.inc")
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
*.inc를 통해 .inc로 들어오는 모든 url을 받을 수 있다.
[Front Servlet 수정]
package front.ctrl;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//*.inc로 들어오는 모든 request를 받는다.
@WebServlet("*.inc")
public class DispatcherServlet extends HttpServlet {
//request 객체를 통해 사용자의 ip나 인코딩 방식을 알아낼 수 있다.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
requestProc(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
requestProc(request, response);
}
protected void requestProc(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String uri = request.getRequestURI();
System.out.println("client uri : " + uri);
}
}
//수정 후 restart



[Controller 생성]
Class로 생성

- Controller의 역할 -
- 파라미터를 Front Controller로부터 넘겨받아서, 때로는 유효성 체크를 진행한다.
- 객체를 생성하고 View에 데이터를 심는 작업을 진행한다.
[Controller 인터페이스 생성]
Ctrl에 사용할 메소드 정의
package com.sinc.intern.util;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Controller {
public void execute(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException;
}
[Ctrl에서 인터페이스의 메소드 구현]
package com.sinc.intern.insa.ctrl;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sinc.intern.util.Controller;
public class SelectCtrl implements Controller{
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("InsertCtrl execute");
}
}
package com.sinc.intern.insa.ctrl;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sinc.intern.util.Controller;
public class InsertCtrl implements Controller{
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("InsertCtrl execute");
}
}
[Factory 생성]
Factory를 통해 Front Controller와 Controller가 연결된다.
Django와 Rails에서 라우터 역할이라 생각하면 될 듯하다.
// 기본 틀
package com.sinc.intern.factory;
import com.sinc.intern.util.Controller;
public class BeanFactory {
private BeanFactory() {
}
public static void getInstance() {
// TODO Auto-generated method stub
}
public Controller getBean(String uri) {
}
}
package com.sinc.intern.factory;
import java.util.Map;
import java.util.HashMap;
import com.sinc.intern.insa.ctrl.InsertCtrl;
import com.sinc.intern.insa.ctrl.SelectCtrl;
import com.sinc.intern.util.Controller;
public class BeanFactory {
private static BeanFactory instance;
private Map<String, Controller> map = new HashMap<>();
private BeanFactory() {
map.put("/incWEB/insert.inc", new InsertCtrl());
map.put("/incWEB/select.inc", new SelectCtrl());
}
public static BeanFactory getInstance() {
if(instance == null) {
instance = new BeanFactory();
}
return instance;
}
public Controller getBean(String uri) {
return map.get(uri);
}
}
[Front에서 Factory를 통해 작업]
들어오는 url바탕으로 ctrl생성
package front.ctrl;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sinc.intern.factory.BeanFactory;
import com.sinc.intern.util.Controller;
@WebServlet("*.inc")
public class DispatcherServlet extends HttpServlet {
//request 객체를 통해 사용자의 ip나 인코딩 방식을 알아낼 수 있다.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
requestProc(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
requestProc(request, response);
}
protected void requestProc(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String uri = request.getRequestURI();
System.out.println("client uri : " + uri);
BeanFactory factory = BeanFactory.getInstance();
Controller ctrl = factory.getBean(uri);
ctrl.execute(request, response);
}
}


[ModelAndView 생성]
Controller와 Front Controller를 이어주기 위해서
package com.sinc.intern.view.util;
public class ModelAndView {
private boolean send;
private String path;
public ModelAndView() {
super();
}
public ModelAndView(boolean send, String path) {
super();
this.send = send;
this.path = path;
}
public boolean isSend() {
return send;
}
public void setSend(boolean send) {
this.send = send;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
@Override
public String toString() {
return "ModelAndView send = " + send + ", path = " + path;
}
}
[반환형 수정 및 Controller 수정]
public interface Controller {
public ModelAndView execute(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException;
}
public class InsertCtrl implements Controller{
@Override
public ModelAndView execute(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("InsertCtrl execute");
ModelAndView mv = new ModelAndView(false, "greeting.jsp");
return mv;
}
}
public class SelectCtrl implements Controller{
@Override
public ModelAndView execute(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("SelectCtrl execute");
ModelAndView mv = new ModelAndView(true, "greeting.jsp");
return mv;
}
}
- 리다이렉션 방법 차이 확인

[Front Controller 수정]
protected void requestProc(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String uri = request.getRequestURI();
System.out.println("client uri : " + uri);
BeanFactory factory = BeanFactory.getInstance();
Controller ctrl = factory.getBean(uri);
ModelAndView mv = ctrl.execute(request, response);
if(mv.isSend()) {
//forward로 처리
RequestDispatcher view = request.getRequestDispatcher(mv.getPath());
view.forward(request, response);
}else {
//sendRedirect로 처리
response.sendRedirect(mv.getPath());
}
}


결론부터 말하자면, 우리는 앞으로 Forward를 이용해 리다이렉션할 것이다.
[분기방식에 따라 데이터를 가져올 수도 못 가져올 수도 있다.]
public class SelectCtrl implements Controller{
@Override
public ModelAndView execute(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("SelectCtrl execute");
ModelAndView mv = new ModelAndView(true, "greeting.jsp");
request.setAttribute("msg", "data");
return mv;
}
}
public class InsertCtrl implements Controller{
@Override
public ModelAndView execute(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("InsertCtrl execute");
ModelAndView mv = new ModelAndView(false, "greeting.jsp");
request.setAttribute("msg", "data");
return mv;
}
}
<%@ 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>
<div align="center">안녕하세요, 반갑습니다.</div>
<hr/>
Result :: ${msg}
</body>
</html>


'웹 프로그래밍 > Web' 카테고리의 다른 글
| [Web] 6. MVC 패턴(5) - 데이터를 심기 위한 session (0) | 2020.01.31 |
|---|---|
| [Web] 5. MVC 패턴(4) - DB연동 (0) | 2020.01.30 |
| [Web] 4. MVC 패턴(3) - 로그인 과정을 통해 알아보는 DAO까지의 흐름 (0) | 2020.01.30 |
| [Web] 3. MVC 패턴(2) - Main과 Param 동작방식 (0) | 2020.01.30 |
| [Web] 1. 환경설정 (0) | 2020.01.29 |