2.    The Interception Filter Pattern

Interception Filter디자인 패턴은 요청을 가로채어 필터에 통과시킨 다음,결과에 따라 요청을 반려시키거나 계속 진행하도록 한다.


사용자 삽입 이미지

Interception FilterJ2EE기반 기술에서 적용한 사례를 든다면 당연히 그 첫번째는Servlet스팩2.3에서부터 지원하게된Servlet Filter가 있을 것이다.

우리는 웹 애플리케이션에서 요청을 처릴 할 때 다음의 몇가지 문제에 대하여 고민하게 된다.

 

n         정상적으로 확인된 클라이언트인가?

n         클라이언트는 유효한Session을 가지고있는가?

n         클라이언트IP는 신뢰할만한 네트워크로부터 왔는가?

n         Request에 신뢰를 위반할 사항이 있는가?

n         클라이언트가 암호화된 자료를 받는다면 어떻게 지원할 것인가?

n         클라이언트의 브라우저 유형을 지원하는가?

 

 

Interception Filter Pattern을 이용한Servelt Filter는 위와 같은 문제점을 쉽게 해결할수 있는 방안을 제공한다.

그림에서 큰 회색박스는 웹 애플리케이션을 나타낸다.필터들은 웹 애플리케이션에 들어오는 모든Request, Response를 인터셉트하도록 되어 있다.필터들은 그림에서 나타난 대로3개의 스택 구조로 되어 있고 각각의Request, Response는 엔드포인트에 도달하기 전에 모든 필터를 거쳐서 가야 한다.각 필터는Request, Response를 조작할 수도 있고,또는 필요한 다른 어떤 일도 할 수 있다.

 

구조


사용자 삽입 이미지

Intercepting Filter pattern class diagram

 


사용자 삽입 이미지

Intercepting Filter sequence diagram

FilterManagerFilterChain의 역할을Servlet Filter에서는Container가 담당한다.

 

역할

n         FilterManager:

필터 관리자는 필터들을 순서대로 정리하고,필터 체인에 필터 처리를 초기화 시켜 필터를 관리한다.

 

n         FilterChain:

필터 체인은 독립적인 필터들이 연속적으로 이루어진 구조이다.

 

n         FilterOne, FilterTwo, FilterThree:

특정한 목적지 또는 목표를 가진 독립적인 필터이다.

 

n         Target:

목표는 클라이언트가 요청한 목적지이다.

 

의도

클라이언트로 부터의 요청을 가로채어 필터에 통과 시킨 다음,결과에 따라 요청을 반려하거나 계속 진행하도록 한다.

 

결론

n         느슨하게 결합한 다루개와 통제를 집권한다.

n         재사용 가능성을 개량한다.

 

n         선언하고는 가동가능한 윤곽.

n         정보 공유는 비능률적이다.(필터들간의 느슨한 결합으로 인하여 정보 공유는 비능률적이다.)

 

예제소스


사용자 삽입 이미지

 

BaseEncodeFilter.java

import java.io.IOException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

 

public class BaseEncodeFilter implements Filter {

   private javax.servlet.FilterConfig myFilterConfig;

 

   public BaseEncodeFilter() { }

 

   public void doFilter(ServletRequest servletRequest,

                        ServletResponse servletResponse,

                        FilterChain filterChain)

   throws IOException, ServletException {

       filterChain.doFilter(servletRequest,

                            servletResponse);

   }

   

   public FilterConfig getFilterConfig() {

       return myFilterConfig;

   }

   

   public void setFilterConfig(FilterConfig filterConfig) {

       myFilterConfig = filterConfig;

   }

 

   public void init(FilterConfig filterConfig)

   throws ServletException {

       myFilterConfig = filterConfig;

   }

 

   public void destroy() {

       myFilterConfig = null;

   }

   

}

 

StandardEncodeFilter.java

import java.io.IOException;

import java.util.Enumeration;

import javax.servlet.FilterChain;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

 

public class StandardEncodeFilter extends BaseEncodeFilter {

 

   public StandardEncodeFilter() { }

   

   public void doFilter(ServletRequest servletRequest,

                        ServletResponse servletResponse,

                        FilterChain filterChain)

   throws IOException, ServletException {

       String contentType = servletRequest.getContentType();

       if ((contentType == null) ||

            contentType.equalsIgnoreCase("application/x-www-form-urlencoded")) {

            System.out.println("StandardEncodeFilterPass");

           translateParamsToAttributes(servletRequest, servletResponse);

       }

       filterChain.doFilter(servletRequest, servletResponse);   

   }

   

   private void translateParamsToAttributes(ServletRequest request,

                                            ServletResponse response) {

       Enumeration paramNames = request.getParameterNames();

       

       while (paramNames.hasMoreElements()) {

           String paramName = (String)paramNames.nextElement();

           String [] values;

           values = request.getParameterValues(paramName);

           

           System.out.println(paramName+" = " + values[0]);

           

           if (values.length == 1)

               request.setAttribute(paramName, values[0]);

           else

               request.setAttribute(paramName, values);

           }

       }

}

 

MultipartEncodeFilter.java

import com.oreilly.servlet.MultipartRequest;

 

import java.io.File;

import java.io.IOException;

 

import java.util.Enumeration;

 

import javax.servlet.FilterChain;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

 

public class MultipartEncodeFilter extends BaseEncodeFilter {

   public MultipartEncodeFilter() { }

 

   public void doFilter(ServletRequest servletRequest,

                        ServletResponse servletResponse,

                        FilterChain filterChain)

   throws IOException, ServletException {

       

       String contentType = servletRequest.getContentType();

 

       if (contentType.startsWith("multipart/form-data")) {

           System.out.println("MultipartEncodeFilterPass");

       

           try {

               String uploadFolder =

               getFilterConfig().getInitParameter("UploadFolder");

               if (uploadFolder == null)

                   uploadFolder = ".";

               

               MultipartRequest multi =

                   new MultipartRequest(servletRequest,

                                        uploadFolder,

                                        1 * 1024 * 1024);

               Enumeration params = multi.getParameterNames();

               

               while (params.hasMoreElements()) {

                   String name = (String)params.nextElement();

                   String value = multi.getParameter(name);

                   System.out.println(name+" = " + value);

                   servletRequest.setAttribute(name, value);

               }

               

               Enumeration files = multi.getFileNames();

               while (files.hasMoreElements()) {

                   String name = (String)files.nextElement();

                   String filename = multi.getFilesystemName(name);

                   String type = multi.getContentType(name);

                   File f = multi.getFile(name);

               }

           } catch (IOException e) {

               System.err.println(e);

           }

       }

       filterChain.doFilter(servletRequest, servletResponse);           

   }

}

 

encodeServlet.java

import java.io.IOException;

import java.io.PrintWriter;

 

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

   private static final String CONTENT_TYPE = "text/html; charset=EUC-KR";

 

   public void init(ServletConfig config) throws ServletException {

       super.init(config);

   }

 

   public void doGet(HttpServletRequest request,

                    HttpServletResponse response)

   throws ServletException, IOException {

       doProcess(request, response);

   }

 

   public void doPost(HttpServletRequest request,

                      HttpServletResponse response)

   throws ServletException, IOException {

       doProcess(request, response);

   }

   

   public void doProcess(HttpServletRequest request,

                          HttpServletResponse response)

   throws ServletException, IOException {

       response.setContentType(CONTENT_TYPE);

       System.out.println("ServeltPass");

       request.setAttribute("isServletPass","servlet Pass OK!");

       RequestDispatcher dispatcher =

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

       dispatcher.forward(request, response);

   }

}

 

web.xml

<?xml version = '1.0' encoding = 'EUC-KR'?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

 

   <description>Empty web.xml file for Web Application</description>

   <filter>

       <filter-name>StandardEncodeFilter</filter-name>

       <display-name>StandardEncodeFilter</display-name>

       <description>

       </description>

       <filter-class>StandardEncodeFilter</filter-class>

   </filter>

   <filter>

       <filter-name>MultipartEncodeFilter</filter-name>

       <display-name>MultipartEncodeFilter</display-name>

       <description>

       </description>

       <filter-class>MultipartEncodeFilter</filter-class>

       <init-param>

           <param-name>UploadFolder</param-name>

           <param-value>D:/</param-value>

       </init-param>

   </filter>

   

   <filter-mapping>

       <filter-name>MultipartEncodeFilter</filter-name>

       <url-pattern>/encodeservlet</url-pattern>

   </filter-mapping>

   <filter-mapping>

       <filter-name>StandardEncodeFilter</filter-name>

       <url-pattern>/encodeservlet</url-pattern>

   </filter-mapping>

   

   <servlet>

       <servlet-name>encodeServlet</servlet-name>

       <servlet-class>encodeServlet</servlet-class>

   </servlet>

   <servlet-mapping>

       <servlet-name>encodeServlet</servlet-name>

       <url-pattern>/encodeservlet</url-pattern>

   </servlet-mapping>

   

   <session-config>

       <session-timeout>35</session-timeout>

   </session-config>

   <mime-mapping>

       <extension>html</extension>

       <mime-type>text/html</mime-type>

   </mime-mapping>

   <mime-mapping>

       <extension>txt</extension>

       <mime-type>text/plain</mime-type>

   </mime-mapping>

</web-app>

 

Index.html

<form name="standard" method="POST" action="encodeservlet">

 <table cellspacing="0" cellpadding="0" border="1" width="100%" align="left">

   <tr>

     <td colspan="2">스텐다드전송</td>

   </tr>

   <tr>

     <td>파라미터1</td>

     <td><input type="text" name="param1" size="15"/></td>

   </tr>

   <tr>

     <td>파라미터2</td>

     <td><input type="text" name="param2" size="15"/></td>

   </tr>

   <tr>

     <td>&nbsp;</td>

     <td><input type="submit" value="전송"/></td>

   </tr>

 </table>

</form>

<form name="multipart" method="POST" action="encodeservlet" enctype="multipart/form-data">

 <table cellspacing="0" cellpadding="0" border="1" width="100%" align="left">

   <tr>

     <td colspan="2">Multipart전송</td>

   </tr>

   <tr>

     <td>파라미터</td>

     <td><input type="text" name="param" size="15"/></td>

   </tr>

   <tr>

     <td>첨부파일</td>

     <td><input type="FILE" name="attfile" size="15"/></td>

   </tr>

   <tr>

     <td>&nbsp;</td>

     <td><input type="submit" value="전송"/></td>

   </tr>

 </table>

</form>

 

output.jsp

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

<%

   java.util.Enumeration keys = request.getAttributeNames();

   String key = "";

   while(keys.hasMoreElements()) {

       key = (String)keys.nextElement();

       out.println("<br>"+key+" : "+request.getAttribute(key));

   }

%>

 

'Programming > Design Pattern' 카테고리의 다른 글

[펌] The Front Controller Pattern  (0) 2006.01.21
[펌] The Composite View pattern  (0) 2006.01.21
[펌] The Front Controller Pattern  (0) 2006.01.21
[펌] The View Helper Pattern  (0) 2006.01.21
[펌] The Composite View pattern  (0) 2006.01.21

Posted by 영웅기삼
,