자바 프로그래밍/Servlet & JSP

Self-Study: Filter

2012. 8. 17. 11:03

필터(Filter)는 요청(Request)을 서블릿에 앞서 중간에서 가로채서 처리한 후 서블릿으로 넘겨주어 서블릿의 수정없이 필요한 처리를 할 수 있다.

필터 적용 대상들

Request 필터:

  • 보안 체크
  • 요청 헤더와 바디 포맷팅 수정
  • 요청 감시와 로그 처리

Response 필터

  • 응답 스트림 압축
  • 응답 스트림 내용 추가 혹은 수정
  • 새로운 응답 스트림 생성

필터의 설정

체인(Chain)식으로 연결하여 사용이 가능하다. 필터는 하나의 완전한 컴포넌트로써 필터간 전처리가 필요없다. 실행 순서를 지정할 수 있다.

필터는 서블릿과 비슷하다.

컨테이너에 선언하고 컨테이너에 의해 호출된다.

컨테이너가 생명주기를 관리한다.

배포기술자(DD)에 설정한다.

필터의 생명주기

  1. init() 메서드 - 컨테이너가 필터를 인스턴스화할 때 호출하므로 필터의 호출 전에 전처리로 설정할 내용을 기술.   FilterConfig 객체 참조를 나중에 쓰기 위하여 지역변수에 저장하는 코드 작성.
  2. doFilter() 메서드 - 컨테이너가 현재 요청에 필터를 적용할 경우 호출. 다음 3개의 인자 사용.
    • ServletRequest 객체
    • ServletResponse 객체
    • FilterChain 객체 - 필터 간의 처리순서를 지정하는 용도. 배포기술자에 지정한 다음 처리 순서의 필터 참조 저장.
  3. destory() 메서드 - 컨터이너가 필터 인스턴스를 제거할 때 호출. 필터 인스턴스 제거전 후처리할 내용 기술.

public class ExampleFilter implements Filter {
	private FilterConfig fg;
	
	/**
	 * 필수 구현 메서드로 일반적으로
	 * FilterConfig 객체 참조를 로컬에 저장하는 용도
	 */
	public void init(FilterConfig config) throws ServletException {
		this.fc = config;
	}
	
	public void doFilter(
			ServletRequst requset,
			ServletResponse response,
			FilterChain chain // 다음 실행해야할 필터 참조
			) throws ServletException, IOException {
		...
		처리할 내용
		...
		
		/* 다음 실행될 필터나 서블릿을 호출. */
		chain.doFilter(request, response);
	}
	
	public void destory() {
		...
		후처리 내용
		...
	}
}

스택에 쌓이는 필터들

다 수의 필터들을 순서대로 처리하기 위해 컨테이너 내에 스택을 두어 처리한다.

필터의 선언 및 실행 순서

배포기술자(DD)에 선언된 매핑 순서를 따른다.



	필터선언명
	필터클래스 패키지 경로
	
		변수명
		
	




	필터선언명
	URL 패턴이나 필터 실행경로




	필터선언명
	서블릿 선언명

※ 컨테이너가 필터 실행 순서를 정하는 규칙

  1. URL 패턴으로 적용되는 필터가 최우선 순위로 체인에 등록된다. 배포기술자에 정의된 순서를 따른다.
  2. URL 패턴으로 일치하는 필터들이 체인에 순서대로 등록되고 난 다음 <servlet-name>으로 일치하는 필터를 찾아 정의된 순서대로 체인에 등록한다.

요청디스패처로 들어오는 요청에 필터 적용(Servlet 2.4 이상)



	필터선언명 
	URL 패턴이나 필터 실행경로 
	
	REQUEST
			AND/OR
	
	INCLUDE
			AND/OR
	
	FORWARD
			AND/OR
	
	ERROR

DB에 저장된 텍스트 중 개행(줄바꿈)문자를 <br> 태그로 바꿔야 할 필요가 있을 때가 종종 있습니다. 입력시에는 텍스트 박스를 이용하지만 브라우저에 텍스트를 뿌릴 때는 개행 위치마다 <br> 태그를 채워넣어야 하죠. 이럴 때, JSTL과 스크립틀릿을 사용하면 간단히 처리할 수 있습니다.

<% pageContext.setAttribute("LF", "\n"); %>

<c:cout> 액션 태그의 escapeXML 속성은 브라우저가 HTML 태그를 해석하여 브라우징할 수 있도록 해주며, fn:replace() 함수를 이용하여 개행문자를 <br> 태그로 바꿔줍니다. 이때 개행문자와 같은 이스케이프 문자는 액션태그가 해석을 할 수 없기 때문에 pageContext를 이용하여 page 생존범위에 LF라는 이름의 변수에 개행문자를 저장하고 fn:replace() 함수에서 사용할 수 있게 해줍니다.

날짜를 DB에 저장할 경우 작업의 편리함이나 효율을 위해 문자열 형태로 저장하거나 DB로부터 프리젠테이션 계층으로 불러올 때 문자열로 변환하여 불러올 경우가 많습니다. MySQL의 JDBC 문서를 봐도 Date 타입은 String 타입으로 매칭시키도록 하고 있습니다.

저의 경우 yyyy-MM-dd 형식의 문자열로 불러온 날짜값을 yyyy/MM/dd 형식으로 화면에 뿌릴 필요가 있었습니다. 물론 JavaScript를 이용하여 변환하거나, JSTL의 fn:replace() 함수를 이용하는 방법도 있겠으나, 둘 다 왠지 꼼수를 쓴다는 느낌이 강해서 정석대로 접근해 봤습니다.

문자열 → 날짜 값 → 날짜 형식 지정



fmt:parseDate 액션태그의 pattern 속성 값을 문자열 형식과 맞추어 해당 문자열을 날짜값date 변수에 저장한 뒤, 다시 fmt:formateDate 액션태그를 이용해서 날짜 형식을 지정해 줍니다. 간단한 예제지만 문자열을 다양한 형식의 날짜 형태로 간단히 뿌릴 수 있고 날짜값으로 변경하였기 때문에 날짜와 관련한 비교 등 연산도 유리합니다.

JSTL의 <fmt> 액션 태그를 이용하여 다국어 지원을 위한 메시지를 출력하는 방법입니다.

  • <fmt:bundle> : 번들 위치 설정
  • <fmt:message> : 번들의 메시지를 출력

message.properties

intranet.title=Intranet
intranet.admin=JeongSam

message_ko_KR.properties

intranet.title=인트라넷
intranet.admin=정샘

test.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>



    intranet.title
intranet.admin
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>





이클립스에서 개발을 해서 웹호스팅 서버로 올려서 관리하다 보면 가끔 귀찮은 상황이 발생을 하곤 합니다. JDBC 설정의 경우도 보통 server.xml에 <Context ...>안에 <Resource>를 이용해서 설정하지만, 이클립스에서 프로젝트 이름을 바꾼다던지 지웠다가 추가한다던지 하면 설정이 지워져서 매번 따로 복사해두었다가 끼워넣곤 합니다. 아마 이미 잘 알고 있겠지만 META-INF/context.xml 파일에 설정을 해 두면 이클립스로 개발할 때 매우 편리합니다.

참고 :

MySQL Reference Manual :: Using Connector/J with Tomcat
http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html#context.xml_configuration

Apache Tomcat 6.0 :: JNDI Resources HOW-TO
http://dev.mysql.com/doc/refman/5.0/en/connector-j-usagenotes-tomcat.html

참고 문서를 보면 톰캣 컨테이너의 리소스($CATALINA_BASE/conf/server.xml)를 설정하는 방법과 개별 웹 어플리케이션별(per-web-application)로 context XML 파일(META-INF/context.xml)을 설정하는 방법이 설명되어 있습니다. 개인적으로는 웹서버에는 server.xml에 설정을 해두고 이클립스에서는 context.xml에 설정을 해서 배포환경과 개발환경을 달리하여 사용하고 있습니다.

설정 예 :

$CATALINA_BASE/conf/server.xml

...

  

...

META-INF/context.xml



           
         

+ Recent posts