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 @Bean와 Filter봄 유형@Configuration
  3. 레지스터 A @Bean와 FilterRegistrationBean봄 유형@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.