JSP MVC 모델 기본 설명 : 모델 2 구조를 이용한 MVC 패턴 구현

[출처] http://dawnisthm.tistory.com/152

< 모델 2 구조를 이용한 MVC 패턴 구현 >

1. 모델 2 구조의 구현 방법 : 기본 MVC 패턴 구현 기법

[SimpleController.java]



package soldesk.mvc;

import java.io.IOException;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class SimpleController extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

processRequest(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

processRequest(request, response);

}

private void processRequest(HttpServletRequest request, HttpServletResponse response)

throws IOException, ServletException {

// 2단계, 요청 파악

// request 객체로부터 사용자의 요청을 파악하는 코드

String type = request.getParameter("type");

// 3단계, 요청한 기능을 수행한다.

// 사용자에 요청에 따라 알맞은 코드

Object resultObject = null;

if (type == null || type.equals("greeting")) {

resultObject = "안녕하세요.";

} else if (type.equals("date")) {

resultObject = new java.util.Date();

} else {

resultObject = "Invalid Type";

}

// 4단계, request나 session에 처리 결과를 저장

request.setAttribute("result", resultObject);

// 5단계, RequestDispatcher를 사용하여 알맞은 뷰로 포워딩

RequestDispatcher dispatcher =

request.getRequestDispatcher("/simpleView.jsp");

dispatcher.forward(request, response);

}

}


[simpleView.jsp]

<%@ page language="java" contentType="text/html; charset=EUC-KR"%>

<html>

<head>

<title>뷰</title>

</head>

<body>

// 컨트롤러가 전달한 값을 읽어옴.

결과 : <%= request.getAttribute("result")%>

</body>

</html>



[WEB-INF\web.xml] 추가

<servlet>

<servlet-name>SimpleController</servlet-name>

<servlet-class>soldesk.mvc.SimpleController</servlet-class>
< /servlet>

<servlet-mapping>

<servlet-name>SimpleController</servlet-name>

<url-pattern>/simple</url-pattern>

</servlet-mapping>


그리고 SimpleController.java 실행시켜 보자.(JSP 페이지 구동시키는 아님을 주의!!)

2. 커맨드 패턴 기반의 코드

컨트롤러 서블릿이 사용자가 어떤 기능을 요청했는지 분석하기 위해 가장 일반적으로 사용하는 방법은 명령어를 사용하는 것이다.

  • 특정 이름의 파라미터에 명령어 정보를 전달한다.
  • 요청 URI 자체를 명령어로 사용한다.

<커맨드 패턴을 이용한 명령어 처리기의 분리>

String commend = request.getParameter("cmd");

CommandHandler handler = null;

if(command == null){

handler = new NullHandler();

}else if{command.equals("BoardList")){

handler = new BoardListHandler();

}else if(command.equals("BoardWriteForm"){

handler = new BoardWriteFormHandler();

}

String viewPage = handler.process(request, response);

RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);

dispatcher.forward(request, response);


명령어를 처리하는 핸들러 클래스들은 CommandHandler 인터페이스를 구현하면 된다.

핸들러 클래스에서 처리해야 작업

public class SimeHandler implements CommandHandler{

public String process(HttpServletRequest request, HttpServletResponse response)

throws Throwable{

// 1. 명령어과 관련된 비즈니스 로직 처리

// 2. 페이지에서 사용할 정보 저장

request.setAttribute("someValue", value);

// 3. 페이지의 URI 리턴

return "/view/someView.jsp";

}

}

3. 설정 파일에 커맨드와 클래스의 관계 명시하기

: <명령어, 명령어 핸들러 클래스> 매핑 정보를 설정 파일에 저장

BoardList = soldesk.command.BoardListHandler

BoardWriteForm = soldesk.command.BoardWriteFormHandler

[ControllerUsingFile.java]

package soldesk.mvc.controller;

import java.io.FileInputStream;

import java.io.IOException;

import java.net.URL;

import java.util.Iterator;

import java.util.Map;

import java.util.Properties;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletConfig;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import soldesk.mvc.command.CommandHandler;

import soldesk.mvc.command.NullHandler;

public class ControllerUsingFile extends HttpServlet {

// <커맨드, 핸들러 인스턴스> 매핑 정보 저장

private Map commandHandlerMap = new java.util.HashMap();

public void init(ServletConfig config) throws ServletException {

String configFile = config.getInitParameter("configFile");

Properties prop = new Properties();

FileInputStream fis = null;

try {

String configFilePath = config.getServletContext().getRealPath(

configFile);

fis = new FileInputStream(configFilePath);

prop.load(fis);

} catch (IOException e) {

throw new ServletException(e);

} finally {

if (fis != null)

try {

fis.close();

} catch (IOException ex) {

}

}

Iterator keyIter = prop.keySet().iterator();

while (keyIter.hasNext()) {

String command = (String) keyIter.next();

String handlerClassName = prop.getProperty(command);

try {

Class handlerClass = Class.forName(handlerClassName);

Object handlerInstance = handlerClass.newInstance();

commandHandlerMap.put(command, handlerInstance);

} catch (ClassNotFoundException e) {

throw new ServletException(e);

} catch (InstantiationException e) {

throw new ServletException(e);

} catch (IllegalAccessException e) {

throw new ServletException(e);

}

}

}

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

process(request, response);

}

protected void doPost(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

process(request, response);

}

private void process(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

String command = request.getParameter("cmd");

CommandHandler handler = (CommandHandler) commandHandlerMap

.get(command);

if (handler == null) {

handler = new NullHandler();

}

String viewPage = null;

try {

viewPage = handler.process(request, response);

} catch (Throwable e) {

throw new ServletException(e);

}

RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);

dispatcher.forward(request, response);

}

}


[WEB-INF\web.xml] 추가

<servlet>

<servlet-name>ControllerUsingFile</servlet-name>

<servlet-class>soldesk.mvc.controller.ControllerUsingFile</servlet-class>

<init-param>

<param-name>configFile</param-name>

<param-value>/WEB-INF/commandHandler.properties</param-value>

</init-param>

</servlet>

<servlet-mapping>

<servlet-name>ControllerUsingFile</servlet-name>

<url-pattern>/controllerUsingFile</url-pattern>

</servlet-mapping>



[commandHandler.properties]

hello = soldesk.mvc.command.HelloHandler

[CommandHandler.java]

package soldesk.mvc.controller;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import soldesk.mvc.command.CommandHandler;

public class CommandHandler {

public String process(HttpServletRequest request, HttpServletResponse response) throws Throwable{

return.setAttribute("hello", "안녕하세요!");

return "/mvc/view/hello.jsp";

}

}


[HelloHandler.java]

package soldesk.mvc.command;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import soldesk.mvc.command.CommandHandler;

public class HelloHandler implements CommandHandler {

public String process(HttpServletRequest request,

HttpServletResponse response) throws Throwable {

request.setAttribute("hello", "안녕하세요!");

return "/mvc/view/hello.jsp";

}

}


[NullHandler.java]

package soldesk.mvc.command;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class NullHandler implements CommandHandler {

@Override

public String process(HttpServletRequest request,

HttpServletResponse response) throws Throwable {

return "/mvc/view/nullCommand.jsp";

}

}


[hello.jsp]

<%@ page contentType = "text/html; charset=euc-kr" %>

<html>

<head><title>Hello</title></head>

<body>

<%= request.getAttribute("hello") %>

</body>

</html>


[nullCommand.jsp]

<%@ page contentType="text/html; charset=euc-kr" %>

<html>

<head><title>에러</title></head>

<body>

잘못된 요청입니다.

</body>

</html>



4. 요청 URI 명령어로 사용하기

: 명령어 기반의 파라미터는 컨트롤러의 URL 사용자에게 노출된다는 단점이 있다.

따라서 URL 일부를 명령어로 사용하여 이런 문제를 방지할 있다.

  • URI 명령어로 사용하기 위해서는 컨트롤러 서블릿의 process()메서드에서 request.getParameter("cmd") 대신

    String command = request.getRequestURI();

    if(command.indexOF(request.getContextPath()) == 0){

    command = command.subString(request.getContextPath().length());

    }

사용하면 된다.



[ControllerUsingURI.java]

package soldesk.mvc.controller;

import java.io.FileInputStream;

import java.io.IOException;

import java.net.URL;

import java.util.Iterator;

import java.util.Map;

import java.util.Properties;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletConfig;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import soldesk.mvc.command.CommandHandler;

import soldesk.mvc.command.NullHandler;

public class ControllerUsingURI extends HttpServlet {

// <커맨드, 핸들러인스턴스> 매핑 정보 저장

private Map commandHandlerMap = new java.util.HashMap();

public void init(ServletConfig config) throws ServletException {

String configFile = config.getInitParameter("configFile2");

Properties prop = new Properties();

FileInputStream fis = null;

try {

String configFilePath = config.getServletContext().getRealPath(

configFile);

fis = new FileInputStream(configFilePath);

prop.load(fis);

} catch (IOException e) {

throw new ServletException(e);

} finally {

if (fis != null)

try {

fis.close();

} catch (IOException ex) {

}

}

Iterator keyIter = prop.keySet().iterator();

while (keyIter.hasNext()) {

String command = (String) keyIter.next();

String handlerClassName = prop.getProperty(command);

try {

Class handlerClass = Class.forName(handlerClassName);

Object handlerInstance = handlerClass.newInstance();

commandHandlerMap.put(command, handlerInstance);

} catch (ClassNotFoundException e) {

throw new ServletException(e);

} catch (InstantiationException e) {

throw new ServletException(e);

} catch (IllegalAccessException e) {

throw new ServletException(e);

}

}

}

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

process(request, response);

}

protected void doPost(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

process(request, response);

}

private void process(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

String command = request.getRequestURI(); // /soldesk/hello.do

if (command.indexOf(request.getContextPath()) == 0) { // /soldesk

command = command.substring(request.getContextPath().length()); // /hello.do

}

CommandHandler handler = (CommandHandler) commandHandlerMap.get(command);

if (handler == null) {

handler = new NullHandler();

}

String viewPage = null;

try {

viewPage = handler.process(request, response);

} catch (Throwable e) {

throw new ServletException(e);

}

RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);

dispatcher.forward(request, response);

}

}


[web.xml]

<servlet>

<servlet-name>ControllerUsingURI</servlet-name>

<servlet-class>soldesk.mvc.controller.ControllerUsingURI</servlet-class>

<init-param>

<param-name>configFile2</param-name>

<param-value>

/WEB-INF/commandHandlerURI.properties

</param-value>

</init-param>

</servlet>

<servlet-mapping>

<servlet-name>ControllerUsingURI</servlet-name>

<url-pattern>*.do</url-pattern>

</servlet-mapping>


[commandHandlerURI.properties]

/hello.do=soldesk.mvc.command.HelloHandler


+ Recent posts