티스토리 뷰
spring boot 학습 & 세팅 3탄 (2.3.9 RELEASE docs.spring.io/spring-boot/docs/2.3.9.RELEASE/reference/html/)
1. @Component 또는 @ServletComponentScan WebFilter)
임베디드 WAS의 경우, 자동 설정에 의해서 Filter를 구현할 클래스에 @Component만 붙여줘도 필터가 등록된다.
@Component
public class FirstFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain chain) throws IOException, ServletException {
.....
}
ServletContextInitializerBeans : Mapping filters: characterEncodingFilter urls=[/*] order=-2147483648,
formContentFilter urls=[/*] order=-9900,
requestContextFilter urls=[/*] order=-105,
firstFilter urls=[/*] order=2147483647
로그를 확인해보면 자동 설정에 의해 디폴트 필터가 3개 등록되었고 추가한 FirstFilter가 마지막으로(urls=[/*] , order=2147483647) 붙었다.
characterEncodingFilter가 Ordered.HIGHEST_PRECEDENCE로 등록되기 때문에 해당값은 피해서 필터 순서를 지정해야 한다.
다른 필터도 마찬가지..
그런데 필터 순서를 지정하지 않았기 때문에 제일 마지막 필터(2147483647)로 등록된다. 필터를 2개 이상 등록해야 한다면 순서를 주기 위해서 @Order 또는 Ordered인터페이스를 구현해야 한다.
@Component
@Order(1)
public class FirstFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain chain) throws IOException, ServletException {
.....
}
ServletContextInitializerBeans :Mapping filters: ...firstFilter urls=[/*] order=1, secondFilter urls=[/*] order=2
로그를 보면 @Order순서에 따라 필터가 잘 등록된 걸 확인할 수 있다.
그런데 @Component로 필터를 등록하면 url패턴을 지정할 수 없기 때문에 기본적으로 모든 url패턴에 매핑된다
@WebFilter 어노테이션을 이용하여 특정 url패턴에 매핑되는 필터를 추가해 보자.
@Component
@Order(2)
@WebFilter(urlPatterns= "/user/*")
public class SecondFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain chain) throws IOException, ServletException {
.....
}
그런데 로그를 보면 secondFilter urls=[/*] order=2 urls이 그대로이다.
@Component로 스캔되서 필터가 등록되었기 때문에 @WebFilter어노테이션이 먹히지 않는다
@ServletComponentScan
spring-boot 내장 웹서버를 사용할 경우 서블릿 Component(@WebFilter,@WebServlet, @WebListener)를 스캔할 때 사용하는 어노테이션이다.
Enables scanning for Servlet components (filters, servlets, and listeners). Scanning is only performed when using an embedded web server.
@SpringBootApplication
@ServletComponentScan
public class ApiApplication {
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
@ServletComponentScan붙여주고 다시 실행해보면 /user/*에 매핑된 걸 확인할 수 있다.
Mapping filters: ....
SecondFilter urls=[/user/*] order=2147483647,
...
secondFilter urls=[/*] order=1
그런데 @ServletComponentScan + @WebFilter로 한 번 등록되고, 또 @Component로 인해 Filter가 또 스캔되면서 필터가 중복해서 등록된다. 따라서 한 번만 등록되도록 @ServletComponentScan + @WebFilter 방식 또는 @Component방식 중에 하나만 적용되도록 해야 한다.
그런데 @WebFilter로 등록하면(SecondFilter urls=[/user/*] order=2147483647) @Order가 안먹히는걸 확인 할 수 있다. (이 경우 필터 ordering은 스캔 순서대로 지정된다.)
정리해보면
1. @Component 방식은 @Order로 순서는 지정할 수 있으나 url패턴 매핑이 불가
2. @ServletComponentScan + @WebFilter 방식은 url매핑은 가능하나 순서 지정 불가
2. FilterRegistrationBean
만약 조금더 세밀한 제어나 Filter클래스를 수정하지 못하는 경우 FilterRegistrationBean을 이용하여 필터를 등록할 수 있습니다. 위에서 정리한 방식에 비해 config 클래스를 별도로 만들어야 하지만 @ServletComponentScan어노테이션이나 필터클래스에 적용한 어노테이션이 필요없습니다.
public class FirstFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain chain) throws IOException, ServletException {
.....
}
@Configuration
public class ServletConfig {
@Bean
public FilterRegistrationBean<SecondFilter> secondFilter(){
FilterRegistrationBean<SecondFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new SecondFilter());
registrationBean.addUrlPatterns("/user/*");
registrationBean.setOrder(2);
registrationBean.setName("second-filter");
return registrationBean;
}
@Bean
public FilterRegistrationBean<FirstFilter> firstFilter(){
FilterRegistrationBean<FirstFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new FirstFilter());
registrationBean.addUrlPatterns("/user/*");
registrationBean.setOrder(1);
registrationBean.setName("first-filter");
return registrationBean;
}
}
setOrder메소드로 순서 설정도 가능하고 addUrlPatthers로 url패턴도 설정 가능하다.
로그를 보면 잘 적용된 걸 확인할 수 있습니다.
Mapping filters: ...
first-filter urls=[/user/*] order=1,
second-filter urls=[/user/*] order=2,
characterEncodingFilter urls=[/*] order=-2147483648,
formContentFilter urls=[/*] order=-9900,
requestContextFilter urls=[/*] order=-105
개인적인 생각
필터 설정이 비교적 간단할 경우에는 @Component나 @WebFilter방식으로 설정해도 무관하나 필터 설정이 조금 복잡하거나 필터가 계속 추가될 여지가 많다면 FilterRegistrationBean를 이용하는 방식이 나을거 같다.
참고
docs.spring.io/spring-boot/docs/2.3.9.RELEASE/reference/htmlsingle/ ....
www.baeldung.com/spring-servletcomponentscan ..
www.baeldung.com/spring-boot-add-filter ..
'Spring-boot' 카테고리의 다른 글
[Spring boot]Redis - Lettuce 설정 (5) | 2021.05.06 |
---|---|
[Spring boot] 초기화 코드 (0) | 2021.04.28 |
[Spring boot]yml configuration (0) | 2021.04.27 |
[Spring boot] undertow (0) | 2021.04.23 |
- Total
- Today
- Yesterday
- neso
- 자바 tcp
- 클라이언트 소켓 유틸
- 상속과 구성
- 자바소켓
- 자바 온라인 사천성
- 사천성 알고리즘
- 자바 소켓통신
- 사천성 게임
- 자바 클라이어트 소켓
- 바이트 기반 서버
- 구성
- 자바 사천성
- 자바 전문통신
- 소켓 유틸
- RedisAutoConfiguration
- 자바 TCP 서버
- 클라이언트 소켓
- 자바 동기화
- client socket util
- 디자인 패턴
- socket connection timeout
- 자바 전문서버
- java socket
- socket readtimeout
- netty
- 추상 팩토리 패턴
- 소켓통신
- java socket util
- 소켓통신 프레임워크
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |