* 본 글은 [뉴렉처]의 Servlet&JSP 프로그래밍 강의를 듣고 정리한 글입니다.
2020 Servlet&JSP 프로그래밍
www.youtube.com
서블릿 필터(Servlet Filter)
- 사용자로부터 요청이 들어오면 WAS(예: Tomcat)는 적절한 소프트웨어(Servlet)를 실행해 Servlet Container에 담아놓고 결과를 돌려줌
- Servlet Container: 서블릿을 실행하면 메모리상에 존재하게 되는데, 그 존재하는 공간
- Servlet이 더이상 실행되지 않으면 Servlet Container에서 삭제됨
- 멀티 바이트 문자 전송 문제의 해결 방법 2가지
- 1) Tomcat 홈 디렉토리>conf>server.xml의 <Connector>태그에 URIEncoding="UTF-8" 삽입
- Tomcat은 여러 애플리케이션을 서비스하는 하나의 컨테이너 > 한 파일 때문에 설정을 바꿔서 다른 파일들에 영향을 주는 건 비효율적
- 2) 서버 설정을 변경할 수 없는 경우, 서블릿마다 request.setCharacterEncoding(”UTF-8”); 작성
- 매번 설정하는 것도 비효율적
- 1) Tomcat 홈 디렉토리>conf>server.xml의 <Connector>태그에 URIEncoding="UTF-8" 삽입
- 위의 문제를 해결하기 위해 서블릿 필터(Servlet Filter) 사용
서블릿 필터(Servlet Filter)
- Servlet 2.3부터 추가된 인터페이스
- 서블릿 실행 전 / 후에 어떤 작업을 할 때 사용
- 클라이언트(브라우저)가 서버로 요청을 보낼 때, 요청이 서블릿으로 전달되기 전/후에 필터링하기 위한 기술
- 사용하기 쉽도록 javax.servlet.Filter 인터페이스로 제공하고 있으며 이것을 구현하고 web.xml에 등록하기만 하면 간단하게 사용할 수 있음
- 필터는 요청이 올 때마다 실행되기도 하지만, Tomcat 서버가 실행될 때도 한 번 실행됨
- 처음 요청할 때 2번 실행되고, 그 다음 요청부터는 한 번 실행됨
필터의 기능
- 서블릿이 호출되기 전에, WAS로부터 전달된 요청(request)를 가로채어 조작/점검
- 서블릿이 실행되기 전에 필터가 먼저 실행됨
- 필터가 실행된 후에 자동으로 서블릿이 실행되는 게 아니라, 서블릿의 실행 여부를 필터가 결정함 (인증과 권한을 책임지는 수문장 역할)
- 웹 컴포넌트(Servlet, Jsp)에서 공통적으로 처리해야 할 기본적인 설정들을 필터에 한 번만 설정하면 됨 (서블릿 각각에 설정할 필요 X)
- 서블릿이 호출되기 전에 HTTP 요청의 헤더를 조작
- 서블릿이 호출된 이후 응답(response)를 출력하기 전에 가로채어 조작
- 서블릿이 실행된 결과 이후에 필터가 실행됨
- 서블릿이 호출된 이후 응답 헤더를 조작
필터 사용 예시
- 로그인여부나 권한 검사와 같은 인증 기능
- 요청이나 응답에 대한 로그(기록) 기능
- 오류 처리 기능
- 데이터 압축이나 변환 기능
- 인코딩 처리 기능
필터 흐름
- HTTP 요청 > WAS > 필터 > 서블릿 > 컨트롤러
필터 제한
- HTTP 요청 > WAS > 필터 > 서블릿 > 컨트롤러 //로그인 사용자
- HTTP 요청 > WAS > 필터(적절하지 않은 요청이라 판단, 서블릿 호출 X) //비 로그인 사용자
- 필터에서 적절하지 않은 요청이라고 판단하면 거기에서 끝낼 수 있음
필터 체인
- HTTP 요청 > WAS > 필터 1 > 필터 2 > 필터 3 > 서블릿 > 컨트롤러
- 필터는 이런 식으로 체이닝 형태로 추가할 수 있음
- 예: 로그를 남기는 필터를 먼저 적용한 다음, 로그인 여부를 체크하는 필터를 추가할 수 있음
필터(Filter) 인터페이스
- init( ): 필터 초기화 메서드. 서블릿 컨테이너가 생성될 때 호출됨
- doFilter( ): 고객의 요청이 올 때마다 해당 메소드가 호출됨. 필터의 로직을 구현하면 됨.
- destroy( ): 필터 종료 메소드. 서블릿 컨테이너가 종료될 때 호출됨
서블릿 필터 만들기
- 클래스 생성할 때 javax.servlet.Filter 인터페이스 구현하도록 설정
- 필터는 요청이 올 때마다 실행되기도 하지만, Tomcat 서버가 실행될 때도 한 번 실행됨
- 처음 요청할 때 2번 실행되고, 그 다음 요청부터는 한 번 실행됨
- 아래의 예시에서는 Tomcat 서버를 실행하면 hello filter가 2번 출력됨
- 필터는 요청이 올 때마다 실행되기도 하지만, Tomcat 서버가 실행될 때도 한 번 실행됨
package com.newlecture.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class CharacterEncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest request
, ServletResponse response
, FilterChain chain)
throws IOException, ServletException {
System.out.println("hello filter");
}
}
서블릿 필터 설정하는 방법 1: web.xml 설정의 <filter>태그
WebContent>WEB-INF>web.xml에서 필터 설정
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.newlecture.web.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 요청이 들어오면 URL 매핑에 맞게 무조건 필터가 실행됨
- 태그 설명
- <filter>태그
- <filter-name>태그: <url-pattern>태그의 매핑이 <filter-class>의 클래스에 의해 정의될 수 있도록 이름 지정
- <filter-class>태그: 어떤 필터 클래스를 사용할지 지정 - 경로까지 다 적어줘야 함 (예: com.newlecture.web.filter.CharacterEncodingFilter)
- <filter-mapping>태그
- <filter-name>태그: 어떤 필터에 대해 어떤 매핑을 할 것이다
- <url-pattern>태그: 어떤 URL 패턴에 대해서만 필터를 적용하도록 설정
- <url-pattern>/*</url-pattern>: 어떤 요청이 와도 모든 URL 패턴에 필터를 적용
- <filter>태그
- 결과 (NoticeReg.java 실행)
- 필터에 설정해둔 문장이 콘솔에 2번 뜸 (Tomcat 실행할 때 한 번, 요청이 들어올 때 한 번)
- 브라우저엔 아무것도 뜨지 않음
- CharacterEncodingFilter는 실행됐으나, NoticeReg는 실행되지 않음
필터 설정 후 서블릿이 실행되지 않는 문제 해결
- 필터(Filter) 인터페이스
- init( ): 필터 초기화 메소드 서블릿 컨테이너가 생성될 때 호출됨
- doFilter( ): 고객의 요청이 올 때마다 해당 메서드가 호출됨. 필터의 로직을 구현하면 됨.
- destroy( ): 필터 종료 메소드. 서블릿 컨테이너가 종료될 때 호출됨
- 필터가 실행된 후 다음으로 넘겨줄지 말지는 **필터의 체인(FilterChain chain)**이 결정
- chain.doFilter(request, response);
- 다음 실행을 관할
- 조건 검사(화이트박스테스트의 종류)를 통해 다음 실행을 어디로 가게 할 것인지 결정할 수도 있음
- 예정대로 가게 할 거라면 doFilter( )를 호출
- 다른 곳으로 전이할 거라면 doFilter( ) 호출하지 않으면 됨
- doFilter( ) 앞에는 필터가 실행되기 전에 쓸 코드를 넣고, doFilter( ) 뒤에는 필터 실행 후 쓸 코드를 넣음
- 필터 실행 순서
- 1) 요청(request)이 오면 doFilter( ) 앞의 필터 코드 실행
- 2) 흐름을 넘겨 다음 필터나 서블릿 실행
- 3) 2번을 실행한 결과는 response로 돌아오고 doFilter( ) 뒤의 필터 코드 실행
System.out.println("before filter"); //1번
chain.doFilter(request, response); //2번
System.out.println("after filter"); //3번
- NoticeReg에 필터 적용 후 서블릿이 실행되지 않는 문제 해결
- 서블릿을 실행하기 전에 요청을 UTF-8로 인코딩하는 필터 먼저 실행
public class CharacterEncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest request
, ServletResponse response
, FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
}
- NoticeReg 서블릿에 요청을 보내는 reg.html 실행 결과
- 1) reg.html 실행
- 2) 요청이 오니까 CharacterEncodingFilter의 doFilter 앞의 코드(요청을 UTF-8로 인코딩하는 코드) 실행
- 3) 다음 흐름으로 넘어가 NoticeReg 서블릿 실행
- 4) 응답을 다시 클라이언트로 보내서 결과 도출
- NoticeReg 서블릿에서는 입력 값을 가져올 때 인코딩 방식이 UTF-8인지 아닌지를 신경쓸 필요가 없음 (필터가 일괄 처리 해주니까)
서블릿 필터 설정하는 방법 2: 어노테이션 @WebFilter
- 1) web.xml의 <filter>, <filter-mapping>태그 제거
- 2) 필터 클래스 위에 어노테이션 @WebFilter 작성
- 예: @WebFilter("/*") (어떤 요청이 와도 모든 URL 패턴에 필터를 적용)
- 어노테이션을 사용하면 불필요한 설정을 할 필요가 없음
- 결과
'☕ Java 웹 프로그래밍 > Servlet & JSP' 카테고리의 다른 글
[Servlet&JSP] 한글이 깨지는 문제 해결방법 최종 정리 (0) | 2023.05.26 |
---|---|
[Servlet&JSP] 학습과제: 사용자 입력을 통한 계산 요청 (4) | 2023.05.26 |
[Servlet&JSP] 사용자 입력: 한글 입력 문제 (2) | 2023.05.24 |
[Servlet&JSP] 사용자 입력: 입력할 내용이 많은 경우는 POST 요청 (2) | 2023.05.24 |
[Servlet&JSP] 사용자 입력: 사용자로부터 입력받은 값으로 GET 요청 (0) | 2023.05.24 |