IT이야기

스프링 부트에서 필터 클래스를 추가하려면 어떻게 해야 하는가?

cyworld 2022. 5. 11. 22:07
반응형

스프링 부트에서 필터 클래스를 추가하려면 어떻게 해야 하는가?

에 대한 주석이 있는가?FilterSpring Boot의 클래스(웹 응용 프로그램용)?아마도@Filter?

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

다음에 대해 언급한 스프링 부트 참조 가이드FilterRegistrationBean, 그러나 나는 그것을 어떻게 사용하는지 확신할 수 없다.

하십시오.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();
}

위 내용은 스프링 부트 1.2.3으로 테스트했다.

여기 스프링 부트 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 {}

}

필터를 추가하는 방법은 세 가지가 있는데

  1. 다음과 같은 스프링 고정관념 중 하나로 필터에 주석 달기@Component
  2. a @Bean와 함께Filter봄에 타이프를 치다@Configuration
  3. a @Bean와 함께FilterRegistrationBean봄에 타이프를 치다@Configuration

사용자 정의 없이 모든 요청에 필터를 적용하려면 #1 또는 #2 중 하나를 사용하고, 그렇지 않으면 #3을 사용하십시오.필터 클래스를 동일한 또는 하위 패키지에 배치하는 한 #1에 대한 구성 요소 검색을 지정할 필요가 없음SpringApplication#3의 경우, #2와 함께 사용하면 Spring이 필터 클래스를 자동 유선 종속성을 가지는 등 관리할 때만 필요하다.의존성 자동 표시/주입이 필요 없는 필터를 새로 만드는 것은 나에게 아주 잘 맞는다.

2번과 3번을 합치면 괜찮지만, 두 번 필터로 끝나지 않는다는 게 놀라웠다.내 추측으로는 스프링이 두 콩을 하나로 결합하여 두 콩을 같은 방법으로 만들어 낸다는 것이다.자동호출과 함께 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;
    }

서블릿 필터를 나타내는 특별한 주석이 없다.당신은 단지 선언한다.@Bean활자의Filter(또는)FilterRegistrationBean예(모든 응답에 사용자 지정 헤더 추가)는 부팅의 자체 EndpointWebMvcAutoConfiguration에 있다.

선언만 하는 경우Filter그것은 모든 요청에 적용될 것이다.또한 a를 추가하는 경우FilterRegistrationBean적용할 개별 서블릿과 URL 패턴을 추가로 지정할 수 있다.

참고:

스프링 부트 1.4를 기준으로,FilterRegistrationBean더 이상 사용되지 않고 단순하게 패키지를 이동하지 않음org.springframework.boot.context.embedded.FilterRegistrationBeanorg.springframework.boot.web.servlet.FilterRegistrationBean

업데이트: 2017-12-16:

Spring Boot 1.5.8에서는 이 작업을 수행하는 두 가지 간단한 방법이 있다.RELEASE는 XML을 필요로 하지 않는다.

첫 번째 방법:

특정 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의 기본적인 스프링 부트 의존성만 있으면 된다(Tomcat 내장 재스퍼는 명시적으로 필요하지 않음).

    <?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>

경고: 첫 번째 방법은 스프링 부트의 컨트롤러가 JSP 파일로 돌아오면 요청이 필터를 두 번 통과시키는 것이다.

한편, 두 번째 방법으로는, 요청은 필터를 한 번만 통과한다.

서블릿 규격의 디폴트 동작과 더 비슷하기 때문에 나는 두 번째 방법을 선호한다.

자세한 테스트 로그는 https://www.surasint.com/spring-boot-webfilter-instead-of-component/를 참조하십시오.

다음은 내 사용자 정의 필터 클래스의 예:

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 Boot 구성에 추가했다.

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;
    }
}

춘계 설명서에 따르면

포함된 서블릿 컨테이너 - 응용프로그램에 서블릿, 필터 또는 수신기 추가

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

예를 들면 다음과 같다.

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

추가 추가@Bean에 대한 구성@Configuration클래스와 필터가 시작 시 등록된다.

또한 클래스 경로 검색을 사용하여 서블릿, 필터 및 수신기를 추가할 수 있으며,

@WebServlet, @WebFilter 및 @WebListener 주석이 달린 클래스는 @ServletComponentScan으로 @Configuration 클래스에 주석을 달고 등록하려는 구성요소가 포함된 패키지를 지정하면 내장된 서블릿 컨테이너에 자동으로 등록할 수 있다.기본적으로 @ServletComponentScan은 주석이 달린 클래스의 패키지에서 스캔한다.

우리는 봄을 이용하여 필터를 등록하기 위해 대략 네 가지 다른 옵션을 가지고 있다.

첫째, 우리는 Spring bean 구현 Filter 또는 확장 HttpFilter를 만들 수 있다.

@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을 확장하는 봄콩을 만들 수 있다.

@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;
    }
}

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

@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);
    }
}

Spring Boot + Spring Security를 사용하는 경우 보안 구성에서 그렇게 할 수 있다.

아래 예에서는 사용자 이름암호 앞에 사용자 정의 필터를 추가하려고 함AuthenticationFilter(모든 기본 Spring Security 필터해당 주문 참조)

@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);
    }
}

@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

    }

}

이 필터는 또한 교차 오리진 액세스를 허용하는 데 도움이 된다.

@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

    }

}

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;
    }
}

링크를 참조하여 전체 응용 프로그램을 확인하십시오.

대답보다는 조언이지만 웹 애플리케이션에서 스프링 MVC를 사용하는 경우 스프링 핸들러를 사용하는 것이 좋은 생각이다.필터 대신 인터셉터.

그것은 같은 일을 할 수 있지만, 또한

  • ModelAndView로 작업 가능
  • 그 방법은 요청 처리 전후 또는 요청 완료 후 호출할 수 있다.
  • 그것은 쉽게 테스트할 수 있다.

1. 핸들러 구현가로채기 인터페이스 및 @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");
    }

}

두 가지 중요한 것이 필요하다.

  • 추가하다@ServletComponentScan메인 클래스로

  • 당신은 그 안에 필터라는 이름의 패키지를 추가할 수 있다.당신이 창조하는 것은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() {
          }
      }
    

@WebFilter javax.servlet.notation을 사용할 수 있다.Javax.servlet을 구현하는 클래스의 WebFilter.필터:

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

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

여기서 많은 해답을 보았지만, 나는 그 해답을 하나도 시도해보지 않았다.나는 다음 코드와 같이 필터를 방금 만들었다.

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() {

    }
}

그리고 남은 스프링 부트 어플리케이션을 그대로 두었다.

사용:

@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... ");
    }

}

을 사용하여 필터를 만들 수도 있다.@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();
    }
}

바실리 코마로프의 대답을 보았다.유사한 접근방법이 있지만 추상 핸들러를 사용한다.처리기를 사용하는 대신 인터셉터어댑터 클래스요격기.

여기 예가 있다...

@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 );
    }

}

이름에서 알 수 있듯이 필터는 리소스에 대한 요청이나 리소스의 응답 또는 둘 다에 대한 필터링을 수행하는 데 사용된다.스프링 부트는 스프링 부트 응용 프로그램에 사용자 정의 필터를 등록할 수 있는 몇 가지 옵션을 제공한다.다른 선택사항들을 살펴봅시다.

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/2018
    }
}

위의 코드에서 몇 가지 중요한 점을 빨리 살펴봅시다.

  • @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 the 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;
    }
}

첫째, 추가@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{

여러분 모두가 알다시피, 스프링 부트는 최소한의 구성과 의견 있는 설정으로 웹 애플리케이션이나 독립 실행형 애플리케이션을 개발하는 훌륭한 방법이다.

이것이 Spring Boot 애플리케이션에서 웹 필터 개발을 완료한 방법이다.

내 SpringBootApp 사양:

스프링 부트 버전: 2.0.4.해제
0 Java 버전: 8.0
3.서블릿 3.0(필수 및 중요)

서블릿 규격 3.0을 준수하면서 다음과 같은 방법으로 웹 필터를 선언하였다.

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

이것은 필터를 web.xml 기반 정의의 대체물로 정의하는 프로그래밍 방식이다.

"@Webfilter" 주석은 배포 중에 컨테이너에 의해 처리된다.발견된 필터 클래스는 구성에 따라 생성되며 URL 패턴인 javax.servlet에 적용된다.서블릿과 자백스.서블릿.디스패처타입스

Web.xml을 완전히 피하고 "Deployable" WebApp을 달성하려면:

스프링 부트 응용 프로그램을 "전통 WAR"로 배포하려면 응용 프로그램 클래스가 SpringBootServlet을 확장해야 함이니셜라이저.

참고:

SpringBootServletInitializer는 WebApplication의 구현이 필요한 Servlet 3.0+ 사양을 참조하는 Web.xml의 "프로그래밍 구현"이다.이니셜라이저.

따라서 SpringBootApplication은 애플리케이션 클래스로 "web.xml"을 요구하지 않는다(SpringBootServlet 확장 후).이니셜라이저).검색한다.

  • @WebFilter,
  • @WebListener 및
  • @WebServlet.

주석 @ServletComponentScan

이 주석은 @WebFilter, @WebListener 및 @WebServlet으로 주석을 단 웹 구성요소에 대한 검색 기본 패키지를 활성화한다.

내장형 컨테이너가 @WebServlet, @WebFilter 및 @WebListener 주석을 지원하지 않기 때문에, 내장형 컨테이너에 크게 의존하는 Spring Boot는 이 새로운 주석 @ServletComponentScan을 도입하여 이 세 개의 주석을 사용하는 일부 종속 JAR 파일을 지원하였다.

스캔은 내장된 서블릿 컨테이너를 사용하는 경우에만 수행된다.

다음은 Spring Boot 애플리케이션 클래스 정의:

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

사용자 지정 서블릿 이니셜라이저:

여기: 사용자 지정 클래스를 정의했다: "서블릿클래스를 확장하는 Initializer: SpringBootServlet이니셜라이저.

앞에서 설명한 대로 SpringBootServletInitializer는 주석 스캔을 담당한다.

  • @WebFilter,
  • @WebListener 및
  • @WebServlet.

따라서 Spring Boot 애플리케이션 클래스는

  • 클래스 확장: SpringBootServlet이니셜라이저 또는
  • 클래스를 확장하는 사용자 지정 클래스를 확장: SpringBootServlet이니셜라이저

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

내가 수행한 모든 구성 클래스의 스프링 부트의 경우:

@Bean
public OncePerRequestFilter myFilter() {
    return new OncePerRequestFilter() {
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            AuthUser authUser = SecurityUtil.safeGet(); // applied after secutiry filters
            ...
            filterChain.doFilter(request, response);
        }
    };
}

그게 다야, 어떤 등록도 필요 없어.OncePerRequestFilter란?를 참조하십시오.

필터는 주로 로거 파일에 사용된다.프로젝트에서 사용하는 로거에 따라 달라진다.

log4j2에 대해 설명하겠다.

<Filters>
    <!-- It prevents an 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 Levels: ALL > TRACE > DEBUG > INFORM > WARN > ERROR > PATAL > OFF의 레벨 순서를 참조하십시오.

참조URL: https://stackoverflow.com/questions/19825946/how-can-i-add-a-filter-class-in-spring-boot

반응형