Spring Boot에서 필터 클래스를 추가하는 방법은 무엇입니까?


229

Filter스프링 부트에 클래스 (웹 애플리케이션 용)에 대한 주석이 있는지 궁금합니다 . 아마도 @Filter?

프로젝트에 사용자 정의 필터를 추가하고 싶습니다.

Spring Boot Reference Guide 에 대해 언급 FilterRegistrationBean했지만 사용법을 잘 모르겠습니다.


@WebFilter로 추가 된 필터는 서블릿 스펙에서 실제 필터처럼 작동하지 않습니다. 그것은 많은 다른 봄 콩을 딴 스프링 콩이 될 것이며 서블릿 코드 전에 실제 필터를 좋아하지 않습니다.
lrxw

정확한 요구 사항을 알려주십시오. ComponentScan에 대한 필터 클래스를 원하면 "@ ComponentScan.Filter"에 대한 주석이 있습니다.
Keaz

답변:


159

타사 필터를 설정하려면을 사용할 수 있습니다 FilterRegistrationBean. 예를 들어 web.xml과 같습니다.

<filter>
     <filter-name>SomeFilter</filter-name>
        <filter-class>com.somecompany.SomeFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SomeFilter</filter-name>
    <url-pattern>/url/*</url-pattern>
    <init-param>
       <param-name>paramName</param-name>
       <param-value>paramValue</param-value>
    </init-param>
</filter-mapping>

이것들은 @Configuration파일 의 두 개의 콩이 될 것입니다

@Bean
public FilterRegistrationBean someFilterRegistration() {

    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(someFilter());
    registration.addUrlPatterns("/url/*");
    registration.addInitParameter("paramName", "paramValue");
    registration.setName("someFilter");
    registration.setOrder(1);
    return registration;
} 

public Filter someFilter() {
    return new SomeFilter();
}

위의 내용은 spring-boot 1.2.3으로 테스트되었습니다.


1
여러 개의 필터를 추가하려면 어떻게합니까? @Opal
verystrongjoe

8
그냥 추가 @Bean 공공 FilterRegistrationBean additionalFilterRegistration () 추가
하임 라만

필터가 적용되는 순서를 어떻게 알 수 있습니까?
BeepDog

7
FilterRegistrationBean.setOrder
Haim Raman

메소드를 someFilter()직접 호출 할 때 필터 Bean이 필요하지 않습니다 .
wst

117

다음은 Spring Boot MVC 애플리케이션에 사용자 정의 필터를 포함시키는 한 가지 방법의 예입니다. 구성 요소 스캔에 패키지를 포함시켜야합니다.

package com.dearheart.gtsc.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

@Component
public class XClacksOverhead implements Filter {

  public static final String X_CLACKS_OVERHEAD = "X-Clacks-Overhead";

  @Override
  public void doFilter(ServletRequest req, ServletResponse res,
      FilterChain chain) throws IOException, ServletException {

    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader(X_CLACKS_OVERHEAD, "GNU Terry Pratchett");
    chain.doFilter(req, res);
  }

  @Override
  public void destroy() {}

  @Override
  public void init(FilterConfig arg0) throws ServletException {}

}

4
어딘가에 필터를 등록해야합니까?
gstackoverflow

1
그 접근법을 시도했을 때, 필터는 bean으로 만들어졌고 심지어 다른 클래스에 주입 되었지만 init () 메소드는 실행되지 않았습니다 . 아마도 init ()는 스프링 컨테이너가 아닌 '정상'등록에서만 작동합니다. 필자는 init () 대신 PostConstruct를 사용할 수 있다고 생각하지만 Filter를 Spring bean으로 선언하는 것을 거부했기 때문에 시도하지 않았습니다.
Baurzhan

이 방법을 사용하는 필터 순서는 어떻습니까?
Pavel Vlasov

ServletResponse에서 RS 본문을 어떻게 얻을 수 있습니까?
user2602807

1
주목해야 할 한 가지 사항은 클래스 이름을 기반으로하는 Bean 이름이 Spring Bean과 동일해서는 안된다는 것입니다. 예를 들어,을 만들고 싶을 수도 MetricsFilter있지만이 Bean은 동일한 이름의 Spring Actuator Bean으로 음영 처리됩니다. 어려운 방법을 배웠습니다 ...
kinbiko

78

서블릿 필터를 나타내는 특수 주석이 없습니다. @Bean유형 Filter(또는 FilterRegistrationBean)을 선언하면 됩니다. 모든 응답에 사용자 정의 헤더를 추가하는 예는 Boot의 자체 EndpointWebMvcAutoConfiguration ;

선언 만하면 Filter모든 요청에 ​​적용됩니다. 당신은 또한을 추가하는 경우 FilterRegistrationBean에는 추가로 개별 서블릿 및 적용 할 URL 패턴을 지정할 수 있습니다.

노트 :

Spring Boot 1.4부터 FilterRegistrationBean 부터는 더 이상 사용되지 않으며 단순히 패키지를 org.springframework.boot.context.embedded.FilterRegistrationBean에서org.springframework.boot.web.servlet.FilterRegistrationBean


build.gradle에 해당 항목을 포함시키는 방법을 알려주시겠습니까? 다음을 추가했지만 컴파일되지 않았습니다. providedCompile ( 'javax.servlet : servlet-api : 2.5') runtime ( 'javax.servlet : jstl : 1.1.2')
janetsmith

2
Spring Boot는 Servlet 2.5에서 작동하지 않으며 아직 JSP를 많이 지원하지 않습니다. 나는 정말 학년이 아니므로, 당신이 무엇을하려고하는지 모르겠습니다. "컴파일"의 문제점은 무엇입니까? "spring-boot-starter-web"에만 의존하면 작동합니까? (이러한 질문이 원래 질문과 관련이 있다고 생각하지 않으므로 새로운 질문으로 다시 게시해야합니까?)
Dave Syer

필터 인터페이스를 구현하여 필터를 추가했지만 Eclipse가 인터페이스를 찾을 수 없습니다. 그래서 컴파일을 위해 클래스 경로에 추가하는 방법을 알아 내려고 노력 중입니다.
janetsmith

1
물론, 당신 Filter은 당신의 학급 에 있어야 합니다. 일반적으로 나는 spring-boot-starter-web모든 관련 depdendencies를 가져 오기 위해 를 사용합니다 (예 : here ).
Dave Syer

다른 응답에 대해 자세히 설명하면 @Component를 사용하여 Filter 클래스에 주석을 달 수 있으며 모든 URL에 대해 자동으로 등록됩니다.
Jakub Holý

72

필터를 추가하는 방법에는 세 가지가 있습니다.

  1. 다음과 같은 Spring 스테레오 타입 중 하나로 필터에 주석을 답니다. @Component
  2. 레지스터 A @BeanFilter봄 유형@Configuration
  3. 레지스터 A @BeanFilterRegistrationBean봄 유형@Configuration

필터를 사용자 정의하지 않고 모든 요청에 ​​적용하려면 # 1 또는 # 2가 수행하고 그렇지 않으면 # 3을 사용하십시오. 필터 클래스를 패키지 클래스와 동일하거나 하위 패키지에 배치하는 한 # 1의 구성 요소 스캔을 지정하지 않아도됩니다.SpringApplication . # 3의 경우 # 2와 함께 사용하면 Spring에서 필터 클래스를 자동 유선 종속성과 같은 필터 클래스로 관리하려는 경우에만 필요합니다. 의존성 자동 배선 / 주입이 필요없는 새로운 필터를 사용하는 것이 좋습니다.

# 2와 # 3을 결합해도 효과가 있지만 두 개의 필터를 두 번 적용하지 않는 것에 놀랐습니다. 내 생각에 Spring은 두 개의 Bean을 생성하기 위해 동일한 메소드를 호출 할 때 두 개의 Bean을 하나로 결합합니다. 인증과 함께 # 3 만 사용하려는 경우을 수행 할 수 있습니다 AutowireCapableBeanFactory. 다음은 예입니다.

private @Autowired AutowireCapableBeanFactory beanFactory;

    @Bean
    public FilterRegistrationBean myFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        Filter myFilter = new MyFilter();
        beanFactory.autowireBean(myFilter);
        registration.setFilter(myFilter);
        registration.addUrlPatterns("/myfilterpath/*");
        return registration;
    }

훌륭한 답변입니다. 모든 옵션을 자세히 설명 Filter하고 사용하는 동안 FilterRegistrationBean
자동 와이어 링

좋은 대답입니다. 이것은 내가 얻은 것입니다 !!
haykart

또한 여기에 설명되어 있습니다 : baeldung.com/spring-boot-add-filter
Jakub Holý

31

업데이트 : 2017-12-16 :

Spring Boot 1.5.8.RELEASE에는 XML이 필요없는 간단한 두 가지 방법이 있습니다.

첫 번째 방법 : Spacific URL 패턴이없는 경우 @Component를 다음과 같이 사용할 수 있습니다 (전체 코드 및 세부 정보는 https://www.surasint.com/spring-boot-filter/ )

@Component
public class ExampleFilter implements Filter{
   ...
}

두 번째 방법 : URL 패턴을 사용하려면 다음과 같이 @WebFilter를 사용할 수 있습니다 (전체 코드 및 세부 정보는 https://www.surasint.com/spring-boot-filter-urlpattern/ )

@WebFilter(urlPatterns = "/api/count")
public class ExampleFilter implements Filter{
 ...
}

그러나 @SpringBootApplication 클래스에 @ServletComponentScan 주석을 추가해야합니다.

@ServletComponentScan
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
...
}

@Component는 Spring의 주석이지만 @WebFilter는 주석이 아닙니다. @WebFilter는 서블릿 3 주석입니다.

두 가지 방법 모두 pom.xml에 기본 스프링 부트 종속성이 필요합니다 (명백한 바람둥이 내장 재스퍼가 필요 없음)

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
    </parent>

    <groupId>com.surasint.example</groupId>
    <artifactId>spring-boot-04</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

경고: 첫 번째 방법은 Spring Boot의 Controller가 JSP 파일로 돌아 가면 요청이 필터를 두 번 전달하는 것입니다.

두 번째 방법으로 요청은 필터를 한 번만 전달합니다.

서블릿 사양의 기본 동작과 더 비슷하기 때문에 두 번째 방법을 선호합니다 ( https://docs.oracle.com/cd/E19879-01/819-3669/6n5sg7b0b/index.html )

https://www.surasint.com/spring-boot-webfilter-instead-of-component/에서 더 많은 테스트 로그를 볼 수 있습니다


FilterapplicationContext를 시작하는 동안 인터페이스가 여러 번 호출되는 것을 보았습니다 . 한 번만 실행할 수있는 방법이 있습니까?
Pra_A

@PAA 내 예에서 의미합니까?
Surasin Tancharoen

20

다음은 내 사용자 정의 필터 클래스의 예입니다.

package com.dawson.controller.filter;

import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@Component
public class DawsonApiFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        if (req.getHeader("x-dawson-nonce") == null || req.getHeader("x-dawson-signature") == null) {
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.setContentType("application/json");
            httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Required headers not specified in the request");
            return;
        }
        chain.doFilter(request, response);
    }
}

그리고 다음과 같이 Configuration 클래스에 추가하여 Spring 부팅 구성에 추가했습니다.

package com.dawson.configuration;

import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
import com.dawson.controller.filter.DawsonApiFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@SpringBootApplication
public class ApplicationConfiguration {
    @Bean
    public FilterRegistrationBean dawsonApiFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new DawsonApiFilter());
// In case you want the filter to apply to specific URL patterns only
        registration.addUrlPatterns("/dawson/*");
        return registration;
    }
}

14

Spring 문서에서

임베디드 서블릿 컨테이너-애플리케이션에 서블릿, 필터 또는 리스너 추가

서블릿, 필터 또는 서블릿 * Listener를 추가하려면 @Bean 정의를 제공하십시오.

예 :

@Bean
public Filter compressFilter() {
    CompressingFilter compressFilter = new CompressingFilter();
    return compressFilter;
}

@Bean구성을 @Configuration클래스에 추가하면 시작시 필터가 등록됩니다.

또한 클래스 경로 스캐닝을 사용하여 서블릿, 필터 및 리스너를 추가 할 수 있습니다.

@WebServlet, @WebFilter 및 @WebListener 어노테이션이있는 클래스는 @ServletComponentScan으로 @Configuration 클래스에 주석을 달고 등록하려는 컴포넌트가 포함 된 패키지를 지정하여 임베디드 서블릿 컨테이너에 자동으로 등록 할 수 있습니다. 기본적으로 @ServletComponentScan은 주석이 달린 클래스의 패키지에서 스캔합니다.



7

Spring Boot + Spring Security를 ​​사용하는 경우 보안 구성에서이를 수행 할 수 있습니다.

아래 예제에서는 UsernamePasswordAuthenticationFilter 앞에 사용자 정의 필터를 추가합니다 ( 모든 기본 스프링 보안 필터 및 순서 참조 ).

@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired FilterDependency filterDependency;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .addFilterBefore(
                new MyFilter(filterDependency),
                UsernamePasswordAuthenticationFilter.class);
    }
}

그리고 필터 클래스

class MyFilter extends OncePerRequestFilter  {
    private final FilterDependency filterDependency;

    public MyFilter(FilterDependency filterDependency) {
        this.filterDependency = filterDependency;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
        HttpServletResponse response,
        FilterChain filterChain)
        throws ServletException, IOException {
       // filter
       filterChain.doFilter(request, response);
    }
}

5

@WebFilter 주석을 사용하여 다음과 같이 수행 할 수 있습니다.

@WebFilter(urlPatterns = {"/*" })
public class AuthenticationFilter implements Filter{

    private static Logger logger = Logger.getLogger(AuthenticationFilter.class);

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest arg0, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

         logger.info("checking client id in filter");
        HttpServletRequest request = (HttpServletRequest) arg0;
        String clientId = request.getHeader("clientId");
        if (StringUtils.isNotEmpty(clientId)) {
            chain.doFilter(request, response);
        } else {
            logger.error("client id missing.");
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

}

3
또한 @ServletComponentScan
Justas

5

Spring을 사용하여 필터등록하는 대략 4 가지 옵션이 있습니다 .

먼저 Filter를 구현 하거나 HttpFilter를 확장 하는 Spring Bean을 만들 수 있습니다 .

@Component
public class MyFilter extends HttpFilter {

    @Override
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) 
        throws IOException, ServletException {
        // Implementation details...

        chain.doFilter(request, response);
    }
}

둘째, GenericFilterBean을 확장하는 Spring bean을 만들 수 있습니다 .

@Component
public class MyFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
  throws IOException, ServletException {
    //Implementation details...

        chain.doFilter(currentRequest, servletResponse);
    }
}

또는 FilterRegistrationBean 클래스를 사용할 수 있습니다 .

@Configuration
public class FilterConfiguration {

    private final MyFilter myFilter;

    @Autowired
    public FilterConfiguration(MyFilter myFilter) {
        this.myFilter = myFilter;
    }

    @Bean
    public FilterRegistrationBean<MyFilter> myFilterRegistration() {
        FilterRegistrationBean<DateLoggingFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(myFilter);
        filterRegistrationBean.setUrlPatterns(Collections.singletonList("/*"));
        filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST);
        filterRegistrationBean.setOrder(Ordered.LOWEST_PRECEDENCE - 1);
        return filterRegistrationBean;
    }
}

마지막으로 @ServletComponentScan 과 함께 @WebFilter 주석을 사용할 수 있습니다 .

@WebFilter(urlPatterns = "/*", dispatcherTypes = {DispatcherType.REQUEST})
public class MyFilter extends HttpFilter {

    @Override
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
  throws IOException, ServletException {
        // Implementation details...

        chain.doFilter(request, response);
    }
}

어떤 필터를 사용해야하며 왜 그런가요?
Pra_A

3

대답보다 조언이되지만 웹 응용 프로그램에서 Spring MVC를 사용하는 경우 필터 대신 Spring HandlerInterceptor를 사용하는 것이 좋습니다

동일한 작업을 수행 할 수 있지만 ModelAndView로 작업 할 수 있습니다. 요청 처리 전후 또는 요청 완료 후에 메소드를 호출 할 수 있습니다.
-쉽게 테스트 할 수 있습니다

1 HandlerInterceptor 인터페이스를 구현하고 클래스에 @Component 주석 추가

@Component
public class SecurityInterceptor implements HandlerInterceptor {

    private static Logger log = LoggerFactory.getLogger(SecurityInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        request.getSession(true);
        if(isLoggedIn(request))
            return true;

        response.getWriter().write("{\"loggedIn\":false}");
        return false;
    }

    private boolean isLoggedIn(HttpServletRequest request) {
        try {
            UserSession userSession = (UserSession) request.getSession(true).getAttribute("userSession");
            return userSession != null && userSession.isLoggedIn();
        } catch(IllegalStateException ex) {
            return false;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

    }
}

2 인터셉터 구성

@Configuration
public class WebConfig implements WebMvcConfigurer {

    private HandlerInterceptor securityInterceptor;

    @Autowired
    public void setSecurityInterceptor(HandlerInterceptor securityInterceptor) {
        this.securityInterceptor = securityInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(securityInterceptor).addPathPatterns("/**").excludePathPatterns("/login", "/logout");
    }

}

간단하고 우아한! 감사합니다
MrMins

3

이 필터는 또한 교차 원점 액세스를 허용하는 데 도움이됩니다.

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCORSFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

            HttpServletResponse response = (HttpServletResponse) res;
            HttpServletRequest request = (HttpServletRequest) req;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            response.setHeader("Access-Control-Max-Age", "20000");
            response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");

            if("OPTIONS".equalsIgnoreCase(request.getMethod())) {
                response.setStatus(HttpServletResponse.SC_OK);
            } else {
                chain.doFilter(req, res);
            }
    }


    public void destroy() {}

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

}

2

javax.servlet.Filter를 구현하는 클래스에서 @WebFilter javax.servlet.annotation.WebFilter를 사용할 수 있습니다.

@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {}

그런 다음 @ServletComponentScan을 사용하여 등록하십시오.


2

나는 여기에 많은 답변을 보았지만 아무 것도 시도하지 않았습니다. 방금 다음 코드와 같이 필터를 만들었습니다.

import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(urlPatterns = "/Admin")
@Configuration
public class AdminFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse  servletResponse, FilterChain filterChain) throws IOException, ServletException      {
    System.out.println("happened");

    }

    @Override
    public void destroy() {

    }
}

나머지 Spring Boot 응용 프로그램은 그대로 두었습니다.


2

두 가지 주요 사항이 필요합니다.- @ServletComponentScan기본 클래스에 추가-내부에 filter라는 패키지를 추가 Filter하면 다음과 같은 클래스를 만들 수 있습니다 .

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestFilter implements Filter {

 // whatever field you have

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
    HttpServletResponse response = (HttpServletResponse) res;
    HttpServletRequest request = (HttpServletRequest) req;

 // whatever implementation you want

        try {
            chain.doFilter(req, res);
        } catch(Exception e) {
            e.printStackTrace();
        }

}

public void init(FilterConfig filterConfig) {}

public void destroy() {}
}

1

@WebFilter를 사용하여 필터를 만들고 Filter를 구현할 수도 있습니다.

 @Configuration
        public class AppInConfig 
        {
        @Bean
      @Order(1)
      public FilterRegistrationBean aiFilterRegistration() {
            FilterRegistrationBean registration = new FilterRegistrationBean();
            registration.setFilter(new TrackingFilter());
            registration.addUrlPatterns("/**");
            registration.setOrder(1);
            return registration;
        } 
    @Bean(name = "TrackingFilter")
        public Filter TrackingFilter() {
            return new TrackingFilter();
        }   
    }

1

이름에 따라 필터링하면 리소스에 대한 요청이나 리소스의 응답 또는 둘 다에서 필터링을 수행하는 데 사용됩니다. 스프링 부트는 스프링 부트 애플리케이션에서 커스텀 필터를 등록하는 옵션이 거의 없다. 다른 옵션을 봅시다.

1. 스프링 부트 필터 및 호출 순서 정의

Spring Boot에서 새 필터를 작성하기 위해 필터 인터페이스를 구현하십시오.

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomFilter implements Filter {

 private static final Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class);

 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
  LOGGER.info("########## Initiating Custom filter ##########");
 }

 @Override
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

  HttpServletRequest request = (HttpServletRequest) servletRequest;
  HttpServletResponse response = (HttpServletResponse) servletResponse;

  LOGGER.info("Logging Request  {} : {}", request.getMethod(), request.getRequestURI());

  //call next filter in the filter chain
  filterChain.doFilter(request, response);

  LOGGER.info("Logging Response :{}", response.getContentType());
 }

 @Override
 public void destroy() {
  // TODO: 7/4/18
 }
}

위 코드에서 몇 가지 중요한 사항을 빠르게 살펴 보겠습니다.

  • @Component 주석으로 등록 된 필터 입니다.
  • 올바른 순서로 필터를 실행하려면 @Order 주석 을 사용해야했습니다 .

    @Component
    @Order(1)
    public class CustomFirstFilter implements Filter {
    
    }
    @Component
    @Order(2)
    public class CustomSecondFilter implements Filter {
    
    }

위 코드에서 CustomFirstFilter는 CustomSecondFilter보다 먼저 실행됩니다.

숫자가 낮을수록 우선 순위가 높습니다

2. URL 패턴

컨벤션 기반 매핑이 충분히 유연하지 않은 경우 FilterRegistrationBean 을 사용 하여 애플리케이션을 완벽하게 제어 할 수 있습니다 . 여기서는 필터 클래스에 @Component 주석을 사용하지 말고 FilterRegistrationBean을 사용하여 필터를 등록하십시오 .

 public class CustomURLFilter implements Filter {

 private static final Logger LOGGER = LoggerFactory.getLogger(CustomURLFilter.class);

 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
  LOGGER.info("########## Initiating CustomURLFilter filter ##########");
 }

 @Override
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

  HttpServletRequest request = (HttpServletRequest) servletRequest;
  HttpServletResponse response = (HttpServletResponse) servletResponse;

  LOGGER.info("This Filter is only called when request is mapped for /customer resource");

  //call next filter in the filter chain
  filterChain.doFilter(request, response);
 }

 @Override
 public void destroy() {

 }
}

FilterRegistrationBean을 사용하여 사용자 정의 필터를 등록하십시오 .

@Configuration
public class AppConfig {

 @Bean
 public FilterRegistrationBean < CustomURLFilter > filterRegistrationBean() {
  FilterRegistrationBean < CustomURLFilter > registrationBean = new FilterRegistrationBean();
  CustomURLFilter customURLFilter = new CustomURLFilter();

  registrationBean.setFilter(customURLFilter);
  registrationBean.addUrlPatterns("/greeting/*");
  registrationBean.setOrder(2); //set precedence
  return registrationBean;
 }
}

1

    @WebFilter(urlPatterns="/*")
    public class XSSFilter implements Filter {

        private static final org.apache.log4j.Logger LOGGER = LogManager.getLogger(XSSFilter.class);

        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            LOGGER.info("Initiating XSSFilter... ");

        }

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            HttpServletRequest req = (HttpServletRequest) request;
            HttpRequestWrapper requestWrapper = new HttpRequestWrapper(req);
            chain.doFilter(requestWrapper, response);
        }

        @Override
        public void destroy() {
            LOGGER.info("Destroying XSSFilter... ");
        }

    }

Filter를 구현해야하며 @WebFilter (urlPatterns = "/ *")로 주석을 달아야합니다.

그리고 Application 또는 Configuration 클래스에서 @ServletComponentScan을 추가해야합니다. 이로 인해 필터가 등록됩니다.


이것은 @WebFilter서블릿 3.0 이후입니다. 그것은 2.5 제대로 작동하지 않을 수 있습니다 그래서
ha9u63ar

1

1 단계 : 필터 인터페이스를 구현하여 필터 구성 요소를 작성하십시오.

@Component
public class PerformanceFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

            ......
            ......
    }

}

2 단계 : FilterRegistrationBean을 사용하여이 필터를 URI 패턴으로 설정하십시오.

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<PerformanceFilter> perfFilter() {
        FilterRegistrationBean<PerformanceFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new PerformanceFilter());
        registration.addUrlPatterns("/*");
        return registration;
    }
}

완전한 신청을 위해이 링크 를 참조 할 수 있습니다 .


0

먼저 @ServletComponentScanSpringBootApplication 클래스에 추가 하십시오.

@ServletComponentScan
public class Application {

둘째, 필터 또는 타사 필터 클래스를 확장하는 필터 파일을 작성하고 다음과 같이이 파일에 추가 @WebFilter하십시오.

@Order(1) //optional
@WebFilter(filterName = "XXXFilter", urlPatterns = "/*",
    dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD},
    initParams = {@WebInitParam(name = "confPath", value = "classpath:/xxx.xml")})
public class XXXFilter extends Filter{

0

@Vasily Komarov의 답변을 보았습니다. 비슷한 접근하지만, 추상적 사용 HandlerInterceptorAdapter의 클래스를 대신 사용 의 HandlerInterceptor를 .

예를 들면 다음과 같습니다.

@Component
public class CustomInterceptor extends HandlerInterceptorAdapter {
   @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
    }
}

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private CustomInterceptor customInterceptor ;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customInterceptor );
    }

}

0

아시다시피 Spring Boot는 최소한의 구성과 의견이있는 설정으로 WebApp 또는 StandaloneApp을 개발하는 훌륭한 방법입니다.

이것이 Spring Boot 응용 프로그램에서 웹 필터 개발을 달성 한 방법입니다

내 SpringBootApp 사양 :-

Spring Boot 버전 : 2.0.4.RELEASE
Java 버전 : 8.0
Servlet 사양 : Servlet 3.0 (필수 및 중요)

Servlet Specification 3.0을 준수하면서 다음과 같은 방식으로 웹 필터를 선언했습니다.

여기에 이미지 설명을 입력하십시오 이것은 web.xml 기반 정의 대신 필터를 정의하는 프로그래밍 방식입니다.

"@Webfilter"어노테이션은 배치 중에 컨테이너에 의해 처리되며, 발견 된 필터 클래스는 구성에 따라 작성되고 URL 패턴 javax.servlet.Servlets 및 javax.servlet.DispatcherTypes에 적용됩니다.

Web.xml을 완전히 피하고 "배포 가능"WebApp을 달성하려면 다음을 수행하십시오.

스프링 부트 어플리케이션을 "전통적 WAR"로 배포하려면 어플리케이션 클래스가 SpringBootServletInitializer를 확장해야합니다.

참고 :: SpringBootServletInitializer는 WebApplicationInitializer의 구현이 필요한 Servlet 3.0+ 사양을 참조하는 web.xml의 "프로그램 구현"입니다.

따라서 SpringBootApplication은 애플리케이션 클래스 (SpringBootServletInitializer를 확장 한 후)가
@WebFilter,
-@WebListener 및
-@WebServlet을 스캔 할 때 "web.xml"을 요구하지 않습니다 .

주석 @ServletComponentScan

이 주석을 사용하면 @WebFilter, @WebListener 및 @WebServlet으로 주석이 달린 웹 구성 요소의 기본 패키지를 검색 할 수 있습니다.

임베디드 컨테이너가 @WebServlet, @WebFilter 및 @WebListener 주석을 지원하지 않기 때문에 스프링 부트는 임베디드 컨테이너에 크게 의존하여이 3 개의 주석을 사용하는 일부 종속 jar을 지원하기 위해이 새로운 주석 @ServletComponentScan을 도입했습니다.

임베드 된 서블릿 컨테이너를 사용하는 경우에만 스캔이 수행됩니다.

다음은 스프링 부트 응용 프로그램 클래스 정의입니다.

여기에 이미지 설명을 입력하십시오

커스텀 서블릿 이니셜 라이저 :-

여기에 클래스 : SpringBootServletInitializer를 확장하는 "ServletInitializer"사용자 정의 클래스를 정의했습니다.

앞에서 설명했듯이 SpringBootServletInitializer는 주석을 스캔합니다 :
--@WebFilter,
-@WebListener 및
-@WebServlet.

따라서 Spring Boot Application Class는

  • 클래스를 확장하십시오. SpringBootServletInitializer 또는
  • 클래스를 확장하는 사용자 정의 클래스 : SpringBootServletInitializer

여기에 이미지 설명을 입력하십시오


-6

필터는 주로 로거 파일에서 사용되며 프로젝트 Lemme에서 log4j2에 설명하는 로거에 따라 다릅니다.

<Filters>
                <!-- It prevents error -->
                <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
                <!-- It prevents debug -->
                <ThresholdFilter level="debug" onMatch="DENY" onMismatch="NEUTRAL" />
                <!-- It allows all levels except debug/trace -->
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> 
            </Filters>

필터는 데이터를 제한하는 데 사용되고 흐름의 데이터 수준을 제한하기 위해 임계 값 필터를 추가로 사용했습니다. 더 많은 참조를 위해서는 log4j2-Log4J 레벨의 레벨 순서를 참조하십시오. ALL> TRACE> DEBUG> INFO> WARN> ERROR> FATAL> OFF


FilterRegistrationBean질문에 언급을위한로 javax.servlet.Filter에 대한이 답변 회담org.apache.logging.log4j.core.Filter
스티브 Buzonas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.