[JSP] EditPlus 주석 단축키 설정

JSP/JSP Setting 2012. 12. 5. 06:28

01. EditPlus 상단의 '도구' → '기본설정'을 선택한다.



02. '키보드' → '편집' → '주석 줄'에서 아래 그림의 순서대로 입력한다.

 -. 새 단축키 누리기 : [ Ctrl + / ]



03. 할당을 누르면 '현재 단축키'로 설정된다.



04. '키보드' → '편집' → '주석 줄 제거'에서 아래 그림의 순서대로 입력한다.

 -. 새 단축키 누리기 : [ Ctrl + \ ]



05. 할당을 누르면 '현재 단축키'로 설정된다.



06. 위 순서대로 작업이 완료되었다면. '적용'을 클릭한다.



07. '확인'을 클릭하면 모든 단축키 설정이 완료된다.



08. 이제 EditPlus에서 새 html 페이지를 열고 전체 내용을 드래그 하고 [ Ctrl + / ]를 누른다.



09. 팝업창의 TextBox에 // 를 입력하고 '확인'을 누르면 설정이 완료된다.




[JSP] 요청 URI 자체를 명령어로 사용하는 방법

JSP/JSP Programming 2012. 8. 31. 11:29

■ 요청 URI 자체를 명령어로 사용하는 방법

 -. 요청 파라미터를 명령어로 사용한느 방법은 간편하기는 하지만

     명령어가 파라미터로 전달되기 때문에 정보가 사용자에게 노출된다는 단점이 있다.

 -. 이런 문제를 방지하기위해서 요청 URI 자체를 명령어로 사용하는 방법이 있다.

 -. 요청 URI 자체를 명령어로 사용하는 방법은 요청되는 URI가 실제 페이지가 아니고 명령어 이므로

    악의적인 명령어로부터 사이트가 보호된다는 점과 요청되는 URL이 좀 더 자연스러워 진다는 점이다.

 -. 요청 URI자체를 명령어로 사용하는 컨트롤러 서블릿(CommandControllerURI)는 요청 파라미터를 명령어로 사용하는

    컨트롤러 서블릿(CommandController)의 proRequest() 메소드에서 String cmd = request.getParameter("cmd"); 를 대신하여

    다음과 같은 코드로 변경하면 된다.

 String cmd = request.getRequestURI();
        
        if(cmd.indexOf(request.getContextPath()) == 0) {
            
            cmd = cmd.substring(request.getContextPath().length());
        }

 -. 위 코드는 요청 URI에서 request.getContextPath() 부분만을 제거하여 cmd 변수에 저장한다.

 -. 웹 브라우저에 입력한 URL을 보면 다음과 같다.

 http://localhost:8181/ch21/ch21/list.do

 -. 여기서는 request.getRequestURI() 메소드에 의해서 얻어낸 요청 URI은 다음과 같다.

  /ch21/ch21/list.do

 -. request.getContextPath()는 웹 어플리케이션 부분인 "/ch21" 부분을 의미한다.

 -. request.getRequestURI() 메소드에 의해서 얻어낸 요청 URI에서 request.getContextPath() 부분을 제거하고 나면

    cmd 변수에 "/ch21/list.do"만 남는다.

 -. 설정 파일에 명령어와 명령어 처리 클래스를 매핑한 정볼르 저장할 때 다음과 같이 저장해야 한다.

  CommandURI.properties
 /ch21/list.do = ch21.controller.ListAction
 /ch21/write.do = ch21.controller.WriteAction


 -. CommandURI.properties 파일을 컨트롤러인 CommandControllerURI에서 읽어올 수 있도록 설정 파일의 정보를 web.xml 파일에 기록한다.

 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"

  xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">

<!--  요청 파라미터로 명령어를 전달하는 방법
  <servlet>
      <servlet-name>CommandController</servlet-name>
      <servlet-class>ch21.controller.CommandController</servlet-class>
      <init-param>
          <param-name>configFile</param-name>
          <param-value>C:\Workspace\ch21\WebContent\WEB-INF\Command.properties</param-value>
      </init-param>
  </servlet>
-->


<!--  요청 URI 자체를 명령어로 사용하는 방법 -->
  <!-- <servlet> 태그는 서블릿의 설정 정보를 처리할 수 있도록 한다. -->
  <servlet>
    <!-- <servlet-name> 태그에는 서블릿명을 기술한다. -->
    <!-- 이 태그를 사용하면 해당 서블릿이 ch21.controller.CommandControllerURI에 위치하더라도 -->
    <!-- http://localhost:8181/ch21/servlet/ch21.controller.CommandControllerURI 대신 -->
    <!-- http://localhost:8181/ch21/servlet/CommandControllerURI로 기술할 수 있다. -->
      <servlet-name>CommandControllerURI</servlet-name>
      <!-- <servlet-class> 태그에는 실제 서블릿 경로를 기술해 준다. -->
      <servlet-class>ch21.controller.CommandControllerURI</servlet-class>
      <!-- <init-param> 태그는 initial parameter를 설정한느 부분으로 -->
      <!-- 이 태그는 config.getInitParameter("configFile") 메소드를 통해 -->
      <!-- 파라미터의 이름을 읽어들여 파라미터의 값을 얻어낸다. -->
      <init-param>
          <!-- <param-name> 태그에는 config.getInitParameter 메소드의 전달인자로 -->
          <!-- 사용할 파라미터의 이름을 기술한다. -->
          <param-name>configFile</param-name>
          <!-- <param-value>는 설정 파일인 CommandURI.properties 파일의 경로명을 기술한다. -->
          <param-value>C:\Workspace\ch21\WebContent\WEB-INF\CommandURI.properties</param-value>
      </init-param>
  </servlet>
 
  <!-- <servlet-mapping> 태그는 <url-pattern> 태그의 값인 *.do와 같이 사용자의 요청이 오는 경우 -->
  <!-- <servlet-name> 태그의 값인 서블릿 CommandControllerURI가 그 요청을 받아서 처리해 주게 하는 것이다. -->
  <!-- 즉 사용자의 요청이 http://localhost:8181/ch21/ch21/list.do 와 같이 오게 되면 -->
  <!-- 이를 CommandControllerURI 서블릿이 처리하도록 환경 설정한다. -->
  <servlet-mapping>
      <servlet-name>CommandControllerURI</servlet-name>
      <url-pattern>*.do</url-pattern>
  </servlet-mapping>

  ~~~~~~~~


</web-app>


 -. 요청 자체를 명령어로 사용하는 컨트롤러 서블릿 작성하기

  CommandControllerURI.java

package ch21.controller;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
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;

public class CommandControllerURI extends HttpServlet {
   
    // 명령어와 명령 처리 클래스를 쌍으로 저장할 해쉬 맵 객체 생성
    private Map commandMap = new HashMap();
   
    public void init(ServletConfig config) throws ServletException {
       
        // web.xml 파일의 configFile 태그의 초기화 파라미터(init-param)로 부터
        // 매핑정보를 저장하고 있는 설정 파일(CommandURI.properties)의 경로를 구한다.
        String configFile = config.getInitParameter("configFile");
       
        if(configFile == null) {
           
            configFile = "C:/Workspace/ch21/WebContent/WEB-INF/CommandURI.properties";
        }
       
        // 명령어와 이를 처리할 클래스의 매핑 정보를 저장할 Properties 객체 생성
        Properties prop = new Properties();
        FileInputStream fis = null;
       
        try {
           
            // 설정 파일(Command.properties)로 부터 파일 내용(매핑 정보)을 읽어온다.
            fis = new FileInputStream(configFile);
           
            // Command.properties 파일의 정보를 Properties 객체에 저장
            prop.load(fis);
        }
       
        catch(IOException e) {
           
            throw new ServletException(e);
        }
       
        finally {
           
            if(fis != null) {
               
                try {
                   
                    fis.close();
                }
               
                catch(IOException e) {
                   
                    e.printStackTrace();
                }
            }
        }
       
        // Properties 객체에서 키값들을 Set으로 얻어와서 iterator 메소드를 호출한다.
        Iterator keyIter = prop.keySet().iterator();
       
        // Iterator 객체로 다음 명령어가 있는지 판단해서 있다면 명령어를 얻어옴
        while(keyIter.hasNext()) {   
           
            String command = (String)keyIter.next();
           
            // 해당 명령어랑 매핑된 클래스 이름을 문자열 형태로 얻어옴
            String className = prop.getProperty(command);
           
            try {
               
                // 클래스의 이름이 문자열 형식이므로 이에 해당되는 클래스 생성
                Class handlerClass = Class.forName(className);
               
                // 해당 클래스로 객체 생성
                Object handlerInstance = handlerClass.newInstance();
               
                // <명령어, 핸들러 인스턴스>의 매핑정보를 해쉬맵에 저장한다.
                commandMap.put(command, handlerInstance);
            }
           
            catch(ClassNotFoundException e) {
               
                throw new ServletException(e);
            }
           
            catch(InstantiationException e) {
               
                throw new ServletException(e);
            }
           
            catch(IllegalAccessException e) {
               
                throw new ServletException(e);
            }
        }
    }
   
    // GET 방식으로 요청을 받음 : proRequest 메소드로 전달
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        proRequest(request, response);
    }
   
    // GET 방식으로 요청을 받음 : proRequest 메소드로 전달
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        proRequest(request, response);
    }
   
    protected void proRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        // Request 객체로부터 사용자의 요청을 파악하는 코드
        String cmd = request.getRequestURI();
       
        if(cmd.indexOf(request.getContextPath()) == 0) {
           
            cmd = cmd.substring(request.getContextPath().length());
        }
       
        // 사용자의 요청에 따른 알맞은 작업을 처리하는 코드
        String view = null;
        CommandAction com = null;
               
        try {
                   
            // 사용자의 요청인 명령어가 저장된 cmd 변수로 이에 해당되는 명령 처리
            com = (CommandAction) commandMap.get(cmd);
                   
            // 인스턴스의 레퍼런스 값을 얻어와서 해당 명령처리 클래스의 proRequest 메소드를 수행 후
            // 포워딩 할 JSP 페이지를 리턴값으로 얻어와 view에 저장한다.
            view = com.proRequest(request, response);
        }
               
        catch(Throwable e) {
                   
            throw new ServletException(e);
        }
               
        // RequestDispatcher를 사용하여 알맞은 뷰(JSP 페이지)로 포워딩
        RequestDispatcher dispatcher = request.getRequestDispatcher(view);
        dispatcher.forward(request, response);
    }
}

 list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>글 목록</title>
</head>
<body>
<%-- message 속성의 값을 msg 변수에 저장한다.--%>
<c:set var = "msg" value = "${message}" />

<%-- msg 변수의 내용을 화면에 출력한다. --%>
<c:out value = "${msg}" />
</body>
</html>
 write.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>글 목록</title>
</head>
<body>
<%-- message 속성의 값을 msg 변수에 저장한다.--%>
<c:set var = "msg" value = "${message}" />

<%-- msg 변수의 내용을 화면에 출력한다. --%>
<c:out value = "${msg}" />
</body>
</html>

 출력화면

 출력화면





[JSP] 서블릿 사용자의 요청을 명령어로 전달

JSP/JSP Programming 2012. 8. 30. 22:06

■ 서블릿 사용자의 요청을 명령어로 전달

 -. 모델 2 기반의 MVC 패턴에서 컨트롤러의 역할을 하는 서블릿은 사용자가 어떤 요청을 했는지 분석해야 한다.

    즉, 사용자가 어떤 페이지를 요청하였는지 구분할 수 있어야 이에 알맞은 모델의 기능을 수행할 수 있게 된다.

 -. MVC 패턴에서 컨트롤러는 사용자가 어떤 요청을 했는지를 명령어를 사용하여 파악한다.

 -. 웹 브라우저를 통해서 명령어를 전달하기 위한 방법은 2가지로 구분된다.

  ① 요청 파라미터로 명령어를 전달하는 방법

  ② 요청 URI 자체를 명령어로 사용하는 방법


01. 요청 파라미터로 명령어를 전달하는 방법

 01) 특정한 이름의 파라미터에 명령어 정보를 담아서 전달

 -. 요청 파라미터로 명령어를 전달하는 방법은 특정한 이름의 파라미터에 명령어 정보를 담아서 전달하는 것이다.


 CommandController01.java
packge ch21.controller;

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 CommandController01 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        proRequest(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        proRequest(request, response);
    }

    protected void proRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        // Request 객체로부터 사용자의 요청을 파악하는 코드
        String cmd = request.getParameter("cmd");       
        String view = null;
       
        // 사용자의 요청에 따른 알맞은 작업을 처리하는 코드
        if(cmd.equals("list")) {
           
            request.setAttribute("message", "글목록 보기");    // 글 목록 보기 작업 수행
            view = "/ch21/list.jsp";
        }
       
        else if(cmd.equals("write")) {
           
            request.setAttribute("message", "글 쓰기");        // 글 쓰기 수행
            view = "/ch21/write.jsp";
        }
       
        RequestDispatcher dispatcher = request.getRequestDispatcher(view);
        dispatcher.forward(request, response);
    }
}
 설명

 -. 파라미터의 이름을 cmd로 하여 명령어를 전달한 것이다.(파라미터 이름은 다른 이름을 사용하여도 상관없다.)

 -. 컨트롤러 역할을 하는 서블릿의 이름을 CommandController01 라고 한다면 파라미터 cmd에 저장된 값에 따라 해당 명령어를 수행하도록 한다.

 list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>글 목록</title>
</head>
<body>
<%-- message 속성의 값을 msg 변수에 저장한다.--%>
<c:set var = "msg" value = "${message}" />

<%-- msg 변수의 내용을 화면에 출력한다. --%>
<c:out value = "${msg}" />
</body>
</html>

 write.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>글 목록</title>
</head>
<body>
<%-- message 속성의 값을 msg 변수에 저장한다.--%>
<c:set var = "msg" value = "${message}" />

<%-- msg 변수의 내용을 화면에 출력한다. --%>
<c:out value = "${msg}" />
</body>
</html>

 력결과①

 력결과②




 02) 커맨드(Command) 패턴으로 작업

  -. 각 명령어에 따른 로직 처리 코드를 별도의 클래스로 작성하는 커맨드(Command) 패턴으로 작업을 처리할 수 있다.

  -. 커맨드 패턴으로 명령어를 처리하기 위해서는 명령 처리 클래스가 있어야 하는데 이는 요청 파라미터를

     동일한 메소드로 처리하도록 하기 위해서 인터페이스를 슈퍼 클래스로 갖도록 한다.

       


 -. 다음은 명령 처리 클래스의 슈퍼 클래스로 사용할 인터페이스를 정의한 문장이다.

  CommandAction.java

package ch21.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface CommandAction {

    public String proRequest(HttpServletRequest request, HttpServletResponse response) throws Throwable;
}

 ListAction.java

package ch21.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ListAction implements CommandAction {

    public String proRequest(HttpServletRequest request, HttpServletResponse response) throws Throwable {
       
        request.setAttribute("message", "글 목록 보기");


        // ListAction 명령 처리 객체는 뷰 페이지로 "/ch21/list.jsp"를 리턴하고 있다.
        return "/ch21/list.jsp";
    }
}

 WriteAction.java

package ch21.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class WriteAction implements CommandAction {

    public String proRequest(HttpServletRequest request, HttpServletResponse response) throws Throwable {
       
        request.setAttribute("message", "글 목록 보기");
       
        // WriteAction 명령 처리 객체는 뷰 페이지로 "/ch21/write.jsp"를 리턴하고 있다.
        return "/ch21/write.jsp";
    }
}

 CommandController02.java

package ch21.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

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;

public class CommandController02 extends HttpServlet {

    // 명령어와 명령 처리 클래스를 쌍으로 저장할 HashMap 객체를 생성한다.
    private Map commandMap = new HashMap();

    // init 메소드는 서블릿이 실행될 때 가장 먼저 단 한번 자동으로 실행된느 메소드이다.
    // init 메소드에서는 명령어와 명령 처리 핸들러의 인터페이스를 HashMap인 commandMap에 키와 값으로 매핑해 둔다.
    public void init(ServletConfig config) throws ServletException {
   
        Object handlerInstance;
        String command;
       
        // list란 명령어를 키로 ListAction 명령 처리 핸들러 인터페이스를 값으로 해쉬맵에 저장한다.
        command = "list";
        handlerInstance = new ListAction();
        commandMap.put(command, handlerInstance);
       
        // write란 명령어를 키로 WriteAction 명령 처리 핸들러 인터페이스를 값으로 해쉬맵에 저장한다.
        command = "write";
        handlerInstance = new WriteAction();
        commandMap.put(command, handlerInstance);
    }

   
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        proRequest(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        proRequest(request, response);
    }

    protected void proRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        // 사용자의 요청을 분석한다. 즉 "..CommandController02?cmd=list"와 같이

        // cmd란 쿼리스트링에 list란 값이 저장되어 있다면 cmd 변수에 list를 저장해 둔다.
        String cmd = request.getParameter("cmd");
        String view = null;
       
        CommandAction com = null;
       
        try {
           
            // 문자열 변수 cmd에 저장된 값을 키로 하여 해쉬 맵에서 이에 해당되는 값을 얻어온다.
            // 즉 cmd에 저장된 값이 "list"이면 ListAction 명령 처리 핸들러 레퍼런스가 얻어진다.
            // CommandAction 인터페이스로 선언된 레퍼런스인 com에 저장한다.
            com = (CommandAction) commandMap.get(cmd);
           
            // 해쉬 맵에서 얻어온 명령 처리 핸들러로 proRequest 메소드를 호출한다.
            // 만일 com에 ListAtion 레퍼런스 값이 저장되어 있다면 이 메소드 내에 기술된 비즈니스 로직이 수행된 후
            // 리턴값인 "ch21/list.jsp"가 view에 저장된 값은 proRequest 메소드의 리턴값은 포워딩될 JSP 페이지다.
            view = com.proRequest(request, response);
        }
       
        catch(Throwable e) {
           
            e.printStackTrace();
        }
       
        // 해당 뷰로 포워딩 하기 위해서 RequestDispatcher 객체를 생성하여 포워딩 한다.
        RequestDispatcher dispatcher = request.getRequestDispatcher(view);
        dispatcher.forward(request, response);
    }
}

 력결과①

 력결과②



 03) 설정 파일 명령어 정보를 담아서 전달

  ① 설정파일에 명령어와 클래스의 관계 명시하기

   -. CommandController02 컨트롤러 서블릿은 명령어와 명령 처리 클래스를 요청이 있을 때 직접 매핑해 주었지만,

      일반적으로 명령어에 따라 처리할 서블릿 클래스가 달라질 수 있도록 하기 위해서 따로 설정 파일을 작성한다.

   -. WEB_INF 폴더에 파일명을 Command.properties로 하여 명령어와 이에 대응하는 명령어처리 클래스를 매핑시킨다.

  Command.properties

 list = ch21.controller.ListAction
 write = ch21.controller.WriteAction

    -. <명령어, 명령어 처리 클래스>와 같은 매핑 구조로 설정 파일에 저장해 두면 새로운 명령어가 추가될 경우 명령어와

       이를 처리할 명령어 핸들러 클래스를 설정 파일에 추가만 시키면 되므로 쉽게 매핑시킬 수 있다는 장점이 있다.


  ② 설정 파일의 정보를 web.xml 파일에 저장하기

    -. Command.properties 파일을 컨트롤러인 CommandController에서 읽어올 수 있도록 설정 파일의 정보를 web.xml 파일에 기록한다.

    -. web.xml 파일에 아래의 문장을 추가해야 한다. 이때 주의할 점은 반드시 이 문장이

       <web_app> 태그 바로 다음에 제일 먼저 나와야 한다는 점이다.

 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"

  xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">


<!-- 요청 파라미터로 명령어를 전달하는 방법 -->

  <!-- <servlet> 태그는 서블릿의 설정 정보를 처리할 수 있도록 한다. -->

  <servlet>
      <!-- <servlet-name> 태그에는 서블릿명을 기술한다. -->
      <!-- 이 태그를 사용하면 해당 서블릿이 ch21.controller.CommandController에 위치하더라도 -->
      <!-- http://localhost:8181/ch21/servlet/ch21.controller.CommandController 대신 -->
      <!-- http://localhost:8181/ch21/servlet/CommandController로 기술할 수 있다. -->
      <servlet-name>CommandController</servlet-name>
      <!-- <servlet-class> 태그에는 실제 서블릿 경로를 기술해 준다. -->
      <servlet-class>ch21.controller.CommandController</servlet-class>
      <!-- <init-param> 태그는 initial parameter를 설정한느 부분으로 -->
      <!-- 이 태그는 config.getInitParameter("configFile") 메소드를 통해 -->

     <!-- 파라미터의 이름을 읽어들여 파라미터의 값을 얻어낸다. -->
      <init-param>
          <!-- <param-name> 태그에는 config.getInitParameter 메소드의 전달인자로 -->

        <!-- 사용할 파라미터의 이름을 기술한다. -->
          <param-name>configFile</param-name>
          <!-- <param-value>는 설정 파일인 Command.properties 파일의 경로명을 기술한다. -->
          <param-value>C:\Workspace\ch21\WebContent\WEB-INF\Command.properties</param-value>
      </init-param>
  </servlet>


  ~~~~~~~~


</web-app>


  ③ 컨트롤러 서블릿 작성하기

   -. 컨트롤러 서블릿은 명령어와 이를 처리할 클래스가 매핑되어 있는 properties 파일에서 읽어 온다.

   -. 명령어와 명령 처리 클래스를 읽어와서 명령 처리 클래스로 인스턴스를 생성하여

      HashMap 객체에 명령어를 키로 명령 처리 인스턴스에 대한 레퍼런스를 값으로 저장해 둔다.

   -. proRequest 메소드에서 명령어에 따른 명령 처리 인스턴스를 접근해서 해당 비즈니스 로직을 수행한 후

      뷰 페이지를 알아내서 해당 페이지로 포워딩 한다.

CommandController.java

package ch21.controller;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
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;

public class CommandController extends HttpServlet {
   
    // 명령어와 명령 처리 클래스를 쌍으로 저장할 해쉬 맵 객체 생성
    private Map commandMap = new HashMap();
   
    public void init(ServletConfig config) throws ServletException {
       
        // web.xml 파일의 configFile 태그의 초기화 파라미터(init-param)로 부터
        // 매핑정보를 저장하고 있는 설정 파일(Command.properties)의 경로를 구한다.
        String configFile = config.getInitParameter("configFile");
       
        if(configFile == null) {
           
            configFile = "C:/Workspace/ch21/WebContent/WEB-INF/Command.properties";
        }
       
        // 명령어와 이를 처리할 클래스의 매핑 정보를 저장할 Properties 객체 생성
        Properties prop = new Properties();
        FileInputStream fis = null;
       
        try {
           
            // 설정 파일(Command.properties)로 부터 파일 내용(매핑 정보)을 읽어온다.
            fis = new FileInputStream(configFile);
           
            // Command.properties 파일의 정보를 Properties 객체에 저장
            prop.load(fis);
        }
       
        catch(IOException e) {
           
            throw new ServletException(e);
        }
       
        finally {
           
            if(fis != null) {
               
                try {
                   
                    fis.close();
                }
               
                catch(IOException e) {
                   
                    e.printStackTrace();
                }
            }
        }
       
        // Properties 객체에서 키값들을 Set으로 얻어와서 iterator 메소드를 호출한다.
        Iterator keyIter = prop.keySet().iterator();
       

        // Iterator 객체로 다음 명령어가 있는지 판단해서 있다면 명령어를 얻어옴
        while(keyIter.hasNext()) {   
           
            String command = (String)keyIter.next();
           
            // 해당 명령어랑 매핑된 클래스 이름을 문자열 형태로 얻어옴
            String className = prop.getProperty(command);
           
            try {
               
                // 클래스의 이름이 문자열 형식이므로 이에 해당되는 클래스 생성
                Class handlerClass = Class.forName(className);
               
                // 해당 클래스로 객체 생성
                Object handlerInstance = handlerClass.newInstance();
               
                // <명령어, 핸들러 인스턴스>의 매핑정보를 해쉬맵에 저장한다.
                commandMap.put(command, handlerInstance);
            }
           
            catch(ClassNotFoundException e) {
               
                throw new ServletException(e);
            }
           
            catch(InstantiationException e) {
               
                throw new ServletException(e);
            }
           
            catch(IllegalAccessException e) {
               
                throw new ServletException(e);
            }
        }
    }
   
    // GET 방식으로 요청을 받음 : proRequest 메소드로 전달
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        proRequest(request, response);
    }
   
    // GET 방식으로 요청을 받음 : proRequest 메소드로 전달
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        proRequest(request, response);
    }
   
    protected void proRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        // Request 객체로부터 사용자의 요청을 파악하는 코드
        String cmd = request.getParameter("cmd");
        CommandAction com = null;
       
        // 사용자의 요청에 따른 알맞은 작업을 처리하는 코드
        String view = null;
       
        try {
           
            // 사용자의 요청인 명령어가 저장된 cmd 변수로 이에 해당되는 명령 처리
            com = (CommandAction) commandMap.get(cmd);
           
            // 인스턴스의 레퍼런스 값을 얻어와서 해당 명령처리 클래스의 proRequest 메소드를 수행 후
            // 포워딩 할 JSP 페이지를 리턴값으로 얻어와 view에 저장한다.
            view = com.proRequest(request, response);
        }
       
        catch(Throwable e) {
           
            throw new ServletException(e);
        }
       
        // RequestDispatcher를 사용하여 알맞은 뷰(JSP 페이지)로 포워딩
        RequestDispatcher dispatcher = request.getRequestDispatcher(view);
        dispatcher.forward(request, response);
    }
}

 력결과①

 력결과②


[JSP] 모델 2 기반의 간단한 MVC 패턴 구현방법

JSP/JSP Programming 2012. 8. 30. 11:20

■ 모델 2 기반의 간단한 MVC 패턴 구현방법

01. 컨틀로러의 역할을 하는 서블릿 클래스

  SampleController.java

package ch21.controller;

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 SampleController extends HttpServlet {
   
    // 1단계 GET 방식으로 요청을 받음 : proRequest 메소드 전달
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        proRequest(request, response);
    }

    // 1단계 POST 방식으로 요청을 받음 : proRequest 메소드 전달
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        proRequest(request, response);
    }

    private void proRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
        // 2단계 Request 객체로부터 사용자의 요청을 파악하는 코드
        String cmd = request.getParameter("cmd");
       
        // 3단계 사용자의 요청에 알맞은 작업을 처리하는 코드
        Object resultObj = null;
       
        if (cmd.equals("eng")) {
           
            resultObj = "Hello!!!";
        }
       
        else if (cmd.equals("kor")) {
           
            resultObj = "안녕하세요!!!";
        }
       
        else {
           
            resultObj = "'eng' 혹은 'kor' 중 하나로 타입을 결정하세요.";
        }
       
        // 4단계 Request 객체의 result 속성에 처리 결과를 지정하는 코드
        request.setAttribute("result", resultObj);
       
        // 5단계 RequestDispatcher를 사용하여 알맞은 뷰(JSP 페이지)로 포워딩
        RequestDispatcher dispatcher = request.getRequestDispatcher("/ch21/sampleView.jsp");
        dispatcher.forward(request, response);
    }
}



02. 뷰의 역할을 하는 JSP

01) *.jar파일 다운 받기

 ① JSTL 스펙 라이브러리 → jstl.jar

 ② JSTL 구현 라이브러리 → standard.jar


02) ch12폴더를 만든 후 sampleView.jsp를 추가혀아 다음과 같이 코딩한다.

  sampleView.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>간단한 컨트롤러의 사용 예</title>
</head>
<body>
<%-- result 속성의 값을 result 변수에 저장한다.--%>

<c:set var = "result" value = "${result}"/>

<%-- result 변수의 내용을 화면에 출력한다.--%>
<c:out value = "${result}"/>
</body>
</html>

 실행과정

 ① 출력화면 - URL : https://localhost:8181/ch21/SampleController

 ② 출력화면 - URL : http://localhost:8181/ch21/SampleController?cmd=eng

 ③ 출력화면 - URL : https://localhost:8181/ch21/SampleController?cmd=kor

 ④ 출력화면 - URL : https://localhost:8181/ch21/SampleController?cmd=?


  • 미래의 모델 2013.09.07 15:50 ADDR 수정/삭제 답글

    모델은 없네요..

[JSP] 모델 2 기반의 MVC 패턴의 개요

JSP/JSP Programming 2012. 8. 29. 11:41

■ 모델 2 기반의 MVC 패턴의 개요

용  어 

설                              명

Model

 -. 정보를 담고 있는 객체, 자바 빈즈를 뜻한다.

View

 -. 정보를 표현하는 객체, JSP(Java Server Page)를 뜻한다.

Controller

 -. 정보를 컨트롤하고 Model과 View 사이를 중재하는 객체이다.

 -. 모델 2에서는 서블릿으로 구현한다.

※ 모델2는 데이터(Model) - 표현(View) - 정보처리(Controller)를 구분하여 재사용과 가독성(읽기 쉽게)을 높이려는 기법이다.


01) 모델 1 구조

 -. JSP로 구현한 기존 웹 어플리케이션은 모델 1 구조로 웹 브라우저의 요청을 JSP 페이지가 받아서 처리하는 구조이다.

 -. JSP 페이지에 비즈니스 로직을 처리하기 위한 코드와 웹 브라우저에 결과를 보여주기 위한 출력 관련 코드가 뒤섞여 있는 구조이다.

 -. 이러한 구조는 JSP 페이지 안에서 모든 정보를 표현(View)하고 저장(Model)하고 처리(Control)되므로 재사용이 힘들고,

    읽기도 힘들어 가독성이 떨어진다.

 모델 1 구조 정리

 -. 정의 : 모든 클라이언트 요청과 응답을 JSP가 담당하는 구조이다.
 -. 장점 : 단순한 페이지 작성으로 쉽게 구현 가능하다. 중소형 프로젝트에 적합하다.

 -. 단점 : 웹 애플리케이션이 복잡해지면 유지보수 문제가 발생된다.


02) 모델 2 구조

 -. 모델 2로 구현한 JSP는 데이터 저장을 자바빈즈가, 데이터처리는 서블릿이, 표현은 JSP가한다.

    이렇게 하여 비즈니스 로직과 데이터, 표현을 완전히 분리해서 처리한다.

 -. JSP와 서블릿을 분리하면 데이터나 비즈니스 로직만을 부분적으로 바꿔도 전체에는 영향이 없을 뿐만 아니라

     다양하게 확장할 수 있는 가능성을 열어두게 된다. 물론 가장 중요한 유지보수 문제도 쉬워진다.


-. 모델 1은 컨트롤러가 모델이나 뷰를 포함한 MV 형태를 띄고 있고, 모델 2는 완전한 MVC 형태를 적용하고 있다고 볼 수 있다.

    바람직한 형태는 모델 2이다.

  모델 2 구조 정리

 -. 정의 : 클라이언트의 요청처리와 응답처리, 비즈니스 로직 처리하는 부분을 모듈화시킨 구조이다.
 -. 장점 : 처리작업의 분리로 인해 유지보수와 확장이 용이하다.
              개발자와 디자이너의 역할과 책임구분이 명확해진다.

              각 컴포넌트의 재사용성이 높아진다.

 -. 단점 : MVC 구조에 대한 이해가 필요하며 개발자의 높은 Skill이 요구된다.


03) MVC 패턴

 -. 프로그램에서 가장 중요한 것이 비즈니스 로직, 즉 데이터를 어떻게 처리하는냐-라는 컨트롤러(Controller)의 역할이다.

 -. JSP에서는 서블릿이 컨틀롤러의 역할을 담당하도록 설계되었다.

 -. 데이터베이스에 접근하는 것은 모델(Model) 객체의 몫이다.

 -. 모델 객체를 UML 클래스 다이어그램을 그린다면 그 자체로 비즈니스 로직으로 표현될 수 있다.

 -. 뷰(View)는 화면 UI를 구성하는 요소이며 일반적으로 웹 어플리케이션에서는 JSP가 뷰의 역할을 맡는다.

-. 컨트롤러는 사용자의 요청을 받아서 모델 객체를 실행하고 그 결과를 뷰로 전달하는 역할을 맡게 되는데 개발자는 어떤 모델을 실행하고

    어떤 뷰를 선택할 것인지를 컨트롤러에 알려주기만 하면 된다.


※ MVC의 핵심

 -. 비즈니스 로직을 처리하는 모델과 결과 화면을 보여주는 뷰가 분리되어 있다.
 -. 어플리케이션의 흐름 제어나 사용자의 요청은 컨트롤러에 집중된다.

① MVC 패턴의 가장 큰 장점은 모델과 뷰의 분리를 통해 화면 UI를 위한 코드와 비즈니스 로직을 위한 코드가 섞이지 않는다는 것이다.

    그래서 화면  UI 개발자와 비즈니스 로직 개발자를 따로 두는 것도 가능하다.

② 또한 모델과 뷰가 분리되면 한 모델에 여러 가지 다양한 뷰를 붙이는 것도 가능하고 그 반대의 경우도 가능하다.

    그래서 요구사항의 복잡도는 높지만 규격이 잘 정해진 애플리케이션을 만들 때는  개발자의 일을 획기적으로 줄일 수 있다.

③ MVC패턴은 결국 이런 모델과 뷰의 분리를 효과적으로 할 수 있는 컨트롤러를 제공한다는데에 그 가치가 있다.


● MVC 패턴의 컨트롤러 : 서블릿

 -. 비즈니스 로직은 모델에서 처리하므로 서블릿은 모델이 내부적으로 어떻게 비즈니스 로직을 처리하는지 알 필요가 없다.

 -. 웹 브라우저의 요청에 맞는 모델을 사용하여 요청한 기능을 수행하고 그 결과를 뷰인 JSP에 전달해 주기만 한다.

 -. 요청 처리 결과는 request나 session  객체에 저장되어 뷰 역할을 하는 JSP 페이지로 전달된다.

 -. 모델 2 구조에서는 서블릿이 컨트롤러의 역할을 담당한다. 컨트롤러의 역할은 다음과 같이 세분화 할 수 있다.

  ① 웹 브라우저(클라이언트)의 요청을 받는다.

  ② 웹 브라우저(클라이언트)가 어떤 기능을 요청했는지 분석한다.

  ③ 분석된 요구사항을 바탕으로 필요한 비즈니스 로직을 처리하는 모델을 호출한다.

  ④ 모델로부터 전달받은 결과물을 알맞게 가공한 후, request나

      session 기본 객체의 setAttribute 메소드를 사용하여 결과값을 속성에 저장한다.

      이렇게 저장된 결과값은 뷰인 JSP에서 사용한다.

  ⑤ 웹 브라우저(클라이언트)에 처리결과를 보여주기 위한 JSP를 선택한 후 해당 JSP를 포워딩한다.


● MVC 패턴의 뷰 : JSP

 -. 모델 2 구조에서 뷰(요청한 결과를 보여주는 프레젠테이션)의 역할은 JSP로 구현한다.

 -. MVC패턴에서 뷰의 역할을 하는 JSP는 비즈니스 로직과 관련도니 코드가 없단느 점을 제외하고는 일반 JSP 페이지와 거의 동일하다.

 -. 다만 request나 session 기본 객체에 저장한 데이터를 사용해서 알맞은 결과를 출력해 준다는 점이 특징다.


● MVC 패턴의 : 자바 빈즈

 -. 모델이 제공해 주는 기능은 웹 브라우저의 요청을 처리하는데 필요한 기능을 제공한다.

 -. 컨트롤러인 서블릿이 웹 브라우저의 요청을 분석하여 알맞은 모델을 호출하면서부터 모델의 기능이 시작한다.

 -. 모델은 컨트롤러가 요청한 작업을 처리한 후 알맞은 결과를 컨트롤러에게 전달해 주는데, 이때 처리한 결과값은 자바빈에 저장된다.

 -. 모델의 역할은 다음과 같이 세분화 할 수 있다.

  ① 컨트롤러로부터 요청을 받는다.

  ② 비즈니스 로직을 수행한다.

  ③ 수행결과를 컨트롤러에 리턴한다.

 

  • wd 2013.06.14 11:33 ADDR 수정/삭제 답글

    정말 설명 상세히 되어있네여. 초보인 저도 이해하기 좋았습니다.