Java Servlet #4

Jay·2023년 4월 14일
0

JAVA

목록 보기
4/4
post-thumbnail

Filter

필터란 서블릿이 수행되기 전이나 후에 추가 기능을 수행할 수 있게 하기 위한 기술이다.

  • 필터 기능을 구현하기 위해서는 서블릿과 별도의 객체로 분리해야 하며 javax.servlet.Filter상속이 필요하다.
  • (필터를 사용하지 않고)서블릿에 기능을 구현하여 처리하는 것도 가능하지만, 필터를 통해 더 유지 보수성이 높은 객체지향적 시스템을 개발할 수 있다.
  • 필터 기능을 통해 대표적으로 로그 기록한글 처리를 수행하는데, 예를 들어 한글 처리를 여러 페이지에서 수행해야 하는 경우를 생각해 보자.
    각 서블릿마다 문자코드를 UTF-8에서 euc-KR로 변경해야 하는 상황이 발생했을 때, 필터를 미리 사용했다면 필터에서만 설정을 변경하면 되지만, 그렇지 않을 경우 모든 서블릿에서 일일이 설정을 변경해야 하는 이슈가 생긴다.

Filter 인터페이스

  • init(FilterConfig)
    * 필터 객체가 생성될 때 호출되며 주로 초기화기능 구현
  • destroy()
    * 필터 객체가 삭제될 때 호출되며 주로 자원해제 기능 구현
  • doFilter(ServletRequest, ServletResponse, FilterChain)
    * 필터링 설정한 서블릿을 실행할 때마다 호출되며 실제 필터링 기능을 구현하는 메서드. init과 destroy와 다르게 서블릿 실행 때마다 호출됨

Filter 작성

FlowFilterOne.java

대략 이런 식으로 필터를 작성했다.
똑같은 모양에 one만 two로 바꾼 FlowFilterTwo.java도 만들어두었음.

Filter 등록

작성한 필터를 사용하기 위해서는 등록이 필요하다.
web.xml

<filter>
	<filter-name>flow1</filter-name>
	<filter-class>com.edu.test.FlowFilterOne</filter-class>
</filter>
	
<filter>
	<filter-name>flow2</filter-name>
	<filter-class>com.edu.test.FlowFilterTwo</filter-class>
</filter>

💡 web.xml 태그 작성 순서
<display-name?>
<description?>
<distributable?>
<context-param>
<filter
>
<filter-mapping>
<listener
>
<servlet>
<servlet-mapping
>
<welcome-file-list?>
<error-page*>

Filter 매핑

이제 등록한 filter를 어떤 서블릿에서 사용할 건지 대상을 설정해주자.
web.xml

<filter-mapping>
	<filter-name>flow1</filter-name>
	<url-pattern>/second</url-pattern>
</filter-mapping>
	
<filter-mapping>
	<filter-name>flow2</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

url-pattern에 /second가 보일 텐데 이전에 annotation을 통해 /second로 연결해주고 있는 서블릿이 하나 있어서, 그 녀석을 연결해주고 있는 것임.

Filter 구현

SecondServlet.java

원래는 저 노란 부분에 doPost였나 그랬는데 service로 변경해줌.
filter랑 service의 관계는 아직 확실히 모르겠음.

여튼 이렇게 연결해준 다음 서블릿을 실행하면 FlowFilterOne 이랑 FlowFilterTwo 에서 적어준 println("doFilter() 호출 전 ...... ")이 각각 출력되고 그 다음에 SecondServlet 내부의 SecondServlet! 이 출력, 마지막으로 호출 후 ......도 각각 출력이 된다.

왜 이런 순서가 되는지 ARABOJA.

  • 클라이언트로부터 http://localhost:8080/second 요청이 들어옴
  • web.xml의 url-pattern(/second) 조건에 만족하기 때문에 flow1필터의 doFilter()메서드가 실행됨(필터 매핑 부분을 보세요)
  • web.xml의 url-pattern(/*)조건에도 만족됨(*는 와일드카드이므로), 따라서 flow2필터의 doFilter()도 실행
  • web.xml에 더 이상의 filter-mapping이 없으므로 클라이언트가 요청한 서블릿이 실행됨(SecondServlet!)

chain.doFilter(req, res);

이 녀석은 doFilter에 3번째 인자로 전달되는 FilterChain 객체이다.
이 녀석은 모든 web.xml의 모든 filter-mapping태그정보를 가지고 있어서 다음에 실행할 메서드가 뭔지를 찾는다.
예를 들어 위에 든 예시에서는 /second를 클라이언트가 요청했을 때 flow1을 실행시킨 후, chain.doFilter가 다음 실행될 flow2를 눈여겨보다가 그 doFilter를 실행한다는 것이다.
만약 chain.doFilter()명령문을 생략해버리면 실행 흐름이 더 이상 진행되지 않고 현재 메서드에서 끝나버리게 된다.

profile
ㄱ이 아닌 개발자가 되고 싶은 사람

0개의 댓글