본문 바로가기
Study/JSPDP

The Decorating Filter Pattern

by epro 2007. 6. 23.
필터를 쓰면 애플리케이션 코드 수정없이 Http request, response 객체를 조작할 수 있다.
즉, 필터가 요청을 중간에서 가로채서 변환시켜 준다.

학습목표
- 필터생성과 응용방법에 대해 알아보자
- 필터의 정의
- 필터 활용 전략

필터 정의
Http Request, response를 가로채서 핵심 애플리케이션에 영향을 미치지 않고 전,후처리가 가능

필터 쓰임
: 로깅, 인증, 데이타 변환, 폼 데이타 검증 과 필요할 경우 프로세싱 차단
* 보충 *
request 필터: 보안, 요청헤더와 바디포캣팅을 수정, 요청을 감시하거나 기록을 남김
response 필터 : 응답 스트림 압축, 응답 스트림에 내용을 추가하거나 수정, 완전히 다른 새로운 응답을 만듬

적용전략
1. 커스텀 필터 개발 전략
자신의 필터링 메카니즘을 적용하기 위해, 커스텀 필터로 얼마든지 핵심 request-processing 로직을 감쌓(wrap)을 수 있다. 핵심 프로세싱 코드가 마지막으로 실행되기 전에 차례로 필터는 실행될 것이다. 한번은 이 필터 체인이 완료됬다. 그러다, 서블릿 컨트롤러가 적당한 뷰를 위해 요청을 dispath한다.
커스텀 필터는 단순히 linted list의 정렬로 만들어져 있다. 각 필터는 각각의 필터가 실행완료 될 때까지 다음 필터체인 로직을 수행한다.
여기에 단점이 있다.
1) 서블릿 컨트롤러 내에 하드코딩을 해야만 한다. 즉 재컴파일을 해야한다.
2) 완료되면 dispatched될 것이라 request와 response 객체를 수정할 수 없다.
(view를 dispatch한다고 했는데 클라이언트로부터들어오는 요청만 필터링 할 수 있으므로 dispatch된 것은 처리할 수 없다는 뜻 같다.)

2. Standard Filter 사용 전략
Servlet2.4API에서는 standard filter를 생성하고 web.xml에 필터를 선언하고 결합시키는 것을 지원한다. 이 필터 전략은 request URL 패턴에 적용된 필터 각각에 차례대로 필터 메니저를 발생시킨다.
각 필터는 "black box"로 요청과 응답을 처리하고 결과를 필터 메니저에게 반환한다. 필터 메니저는 다음 필터체인을 실행하고, 마지막 필터 체인이 끝나고 target resource에 도착할 때까지 계속된다.
이 메카니즘의 장점은,
1) 애플리케이션 코드에 영향을 미치지 않고 HTTP request, response에 필터를 추가, 제거할 수 있다.
(web.xml에 mapping만 시켜주면 되니까..)
2) 출력스트림 뿐만 아니라 요청 객체도 수정할 수 있다. 왜냐하면 이 프로세스는 서블릿 컨트롤러 밖에서 일어나기 때문이다.
(HTTPServletREsponseWrapper를 쓸 수 있으니까 그렇겠지?)

아래 클래스 다이어그램을 Decorating Filter pattern으로다시 그려보면,

사용자 삽입 이미지

순차적인 다이어그램으로 표현된다.
사용자 삽입 이미지

필터체인
: 필터는 모듈로 블록처럼 쌓을 수 있도록 고안된 것이기에 다양한 방식으로 섞어서 사용할 수 있다.
필터체인은 다음에 실행할 필터가 무엇인지 알고 있다.
(순서는 DD에 선언한 순서 임)

필터 선언
<filter>
  <filter-name>MyFilter</filter-name>
  <filter-class>net.agilejava.jspdp.MyFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>MyFilter</filter-name>
  <url-pattern>*.do</url-pattern>  <!-- URL 패턴과 필터 매핑 선언-->
</filter-mapping>
<filter-mapping>
  <filter-name>MyFilter</filter-name>
  <servlet-name>AdviceServlet</servlet-name>  <!-- 서블릿 이름에 필터매칭 선언-->
</filter-mapping>

컨테이너가 필터 순서 정하는 규칙
1) url패턴으로 적용되는 필터가 제일 먼저 옴.
클라이언트가 요청을 날릴 때, 일치하는 모든 필터를 모두 체인에 넣고 하나씩 실행함.
2) URL패턴으로 일치하는 필터들이 체인에 모두 들어가고 난 다음 <servlet-name>으로 일치하는 필터를 찾아 그 정의된 순서대로 체인에 등록함.

의문점!!!!
클라이언트로부터 들어오는 요청을 필터링하는 기능은 제공하지만 forward나 request dispatch를 통해 들어오는 요청은 처리할 줄 모르네요...
=> Servlet2.4부터 request dispatch로 들어오는 요청도 필터를 적용할 수 있답니다!
<filter-mapping>
   <filter-name>CheckFilter</filter-name>
   <url-pattern>*.do</url-pattern>
   <dispatcher>REQUEST</dispatcher>   <!-- dispatcher항목이 없을 때 REQUEST가 디폴트 -->
                    -  OR / AND -
   <dispatcher>INCLUDE</dispatcher>
                    -  OR / AND -
   <dispatcher>FORWARD</dispatcher>
                    -  OR / AND -
   <dispatcher>ERROR</dispatcher> 
</filter-mapping>


Reference
Foundations of JSP Design Pattern / Apress
Head First Servlet & JSP / O'REILLY
http://java.sun.com/j2ee/patterns/DecoratingFilter.html

댓글