Spring Bootでフィルタークラスを追加する方法


229

FilterSpring Bootのクラス(Webアプリケーション用)に注釈があるかしら。たぶん@Filter

プロジェクトにカスタムフィルターを追加したい。

スプリングブートリファレンスガイドについて FilterRegistrationBean説明しましたが、その使用方法がわかりません。


@WebFilterで追加されたフィルターは、サーブレット仕様の実際のフィルターのように動作しないことに注意してください。これは、他の多くのSpring Beanの後に呼び出されるSpring Beanであり、サーブレットコードの前の実際のフィルターとは異なります。
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ファイル内の2つのBeanになります

@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 public FilterRegistrationBean additionalFilterRegistration()を追加するだけです
Haim Raman

フィルターが適用される順序はどのようにしてわかりますか?
BeepDog 2016年

7
FilterRegistrationBean.setOrder
Haim Raman

メソッドをsomeFilter()直接呼び出す場合、フィルターBeanは必要ありません。
wst '14 / 03/17

117

以下は、Spring Boot MVCアプリケーションにカスタムフィルターを含める1つの方法の例です。必ずパッケージをコンポーネントスキャンに含めてください。

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
その方法を試したところ、FilterはBeanとして作成され、他のクラスにも注入されましたが、init()メソッドは実行されませんでした。おそらく、init()は「通常の」登録でのみ機能し、Springコンテナでは機能しません。私は、init()の代わりにPostConstructを使用することもできると思いますが、私はFilterをSpring Beanとして宣言することを拒否したため、それを試みませんでした。
Baurzhan 2016年

このアプローチを使用したフィルターの順序付けについてはどうですか?
Pavel Vlasov

RS本体をServletResponseから取得するにはどうすればよいですか?
user2602807 2017年

1
注意すべき重要な点の1つは、Beanの名前(クラス名に基づく)がSpring Beanと同じであってはならないということです。たとえば、を作成したくなるかもしれませんがMetricsFilter、このBeanは同じ名前のSpringアクチュエータBeanによって影を落とされます。これを一生懸命学びました...
kinbiko 2017年

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:サーブレットAPI:2.5')ランタイム( 'のjavax.servlet:JSTL:1.1.2')
janetsmith

2
Spring BootはServlet 2.5では機能しません。また、JSPのサポートはまだまだ多くありません。私は本当は卒業生ではないので、あなたが何をしようとしているのかわかりません。「コンパイル」の何が問題になっていますか?「spring-boot-starter-web」だけに依存している場合は機能しますか?(ただし、これらの質問は元の質問に関連しているとは思わないので、新しい質問をもう一度投稿する必要がありますか?)
Dave Syer 2013年

Filterインターフェースを実装してフィルターを追加しましたが、Eclipseがインターフェースを見つけることができません。だから私はそれをコンパイルするためにクラスパスに追加する方法を理解しようとしています。
janetsmith 2013年

1
はい、もちろんあなたFilterはあなたのクラスパスに持っている必要があります。通常、私はを使用しspring-boot-starter-webて、関連するすべての依存関係を取得します(例:ここ)。
Dave Syer、2013年

他の応答の詳細として、@ Componentを使用してFilterクラスに注釈を付けることもでき、それは(すべてのURLに対して)自動的に登録されます。
JakubHolý

72

フィルターを追加する方法は3つあります。

  1. 次のようなSpringステレオタイプの1つでフィルターに注釈を付けます。 @Component
  2. Spring @BeanFilter型を登録する@Configuration
  3. Spring @BeanFilterRegistrationBean型を登録する@Configuration

フィルターをカスタマイズせずにすべてのリクエストに適用したい場合は#1または#2のいずれかを実行し、それ以外の場合は#3を使用します。フィルタークラスをクラスの同じパッケージまたはサブパッケージに配置する限り、#1のコンポーネントスキャンを指定する必要はありませんSpringApplication。#3の場合、#2と一緒に使用する必要があるのは、Springでフィルタークラスを管理する場合(依存関係を自動配線するなど)だけです。依存関係のオートワイヤリング/インジェクションを必要としない新しいフィルターを使用することで、問題なく動作します。

#2と#3を組み合わせると問題なく動作しますが、2つのフィルターが2回適用されないことに驚きました。私の推測では、Springは同じメソッドを呼び出して両方を作成するときに、2つのBeanを1つに結合します。認証で#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
sbk

すばらしい答えです。これがまさに私が勝ったものです!
haykart 2017年

これについてもここで説明されています:baeldung.com/spring-boot-add-filter
JakubHolý

31

更新:2017-12-16:

Spring Boot 1.5.8.RELEASEでこれを行う簡単な方法は2つあり、XMLは必要ありません。

最初の方法: 特別なURLパターンがない場合は、 @Componentを使用できます(完全なコードと詳細はこちらhttps://www.surasint.com/spring-boot-filter/

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

2番目の方法: 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はServlet 3アノテーションです。

どちらの方法でも、pom.xmlに基本的なSpring Boot依存関係が必要なだけです(明示的なtomcat組み込みjasperは不要)。

    <?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のコントローラーがJSPファイルに戻ると、リクエストはフィルターを2回通過します。

一方、2番目の方法では、リクエストはフィルターを1回だけ通過します。

サーブレット仕様のデフォルトの動作(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

これが私のカスタムFilterクラスの例です。

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 docsから、

組み込みサーブレットコンテナー-サーブレット、フィルター、またはリスナーをアプリケーションに追加します

サーブレット、フィルター、またはサーブレット*リスナーを追加するには、@ Bean 定義を提供します。

例えば:

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

この@Bean設定を@Configurationクラスに追加すると、起動時にフィルターが登録されます。

また、クラスパススキャンを使用して、サーブレット、フィルタ、リスナーを追加できます。

@ WebServlet、@ WebFilter、および@WebListenerのアノテーション付きクラスは、@ Configurationクラスに@ServletComponentScanアノテーションを付け、登録するコンポーネントを含むパッケージを指定することにより、埋め込みサーブレットコンテナーに自動的に登録できます。デフォルトでは、@ ServletComponentScanは注釈付きクラスのパッケージからスキャンします。



7

Spring Boot + Spring Securityを使用する場合は、セキュリティ構成で行うことができます。

以下の例では、UsernamePasswordAuthenticationFilterの前にカスタムフィルターを追加していますすべてのデフォルトの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);
    }
}

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

最後に、@ 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);
    }
}

使用するフィルターとその理由は?
Pra_A

3

回答というよりアドバイスですが、WebアプリケーションでSpring MVCを使用している場合は、Filterではなく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

あなたは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を使用してフィルターを作成し、フィルターを実装することもできます。

 @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

名前が示すフィルターは、リソースへの要求またはリソースからの応答のいずれか、あるいはその両方でフィルタリングを実行するために使用されます。Spring Bootは、Spring Bootアプリケーションにカスタムフィルターを登録するためのいくつかのオプションを提供します。さまざまなオプションを見てみましょう。

1. Spring Boot Filterと呼び出し順序を定義する

Filterインターフェースを実装して、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 {
    
    }

上記のコードでは、CustomSecondFilterの前にCustomFirstFilterが実行されます。

数値が小さいほど、優先順位は高くなります

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 = "/ *")で注釈を付ける必要があります

そして、アプリケーションまたは構成クラスで@ServletComponentScanを追加する必要があります。これにより、フィルターが登録されます。


これ@WebFilterはサーブレット3.0以降のみです。したがって、2.5では適切に機能しない可能性があります
ha9u63ar

1

手順1:Filterインターフェイスを実装して、フィルターコンポーネントを作成します。

@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 {

次に、Filterまたはサードパーティのフィルタークラスを拡張するフィルターファイルを作成し、次の@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の答えを見ました。同様のアプローチですが、HandlerInterceptor を使用する代わりに、抽象HandlerInterceptorAdapterクラスを使用します

ここに例があります...

@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アプリケーションでWebフィルター開発を達成した方法です

私のSpringBootApp仕様:-

Spring Bootバージョン:2.0.4.RELEASE
Javaバージョン:8.0
サーブレット仕様:サーブレット3.0(必須および重要)

サーブレット仕様3.0に準拠して、次の方法でWebフィルターを宣言しました

ここに画像の説明を入力してください これは、web.xmlベースの定義の代わりとしてフィルターを定義するプログラム的な方法です。

「@Webfilter」アノテーションはデプロイ時にコンテナによって処理され、それが見つかったFilterクラスは構成に従って作成され、URLパターン、javax.servlet.Servletsおよびjavax.servlet.DispatcherTypesに適用されます。

Web.xmlを完全に回避し、「展開可能な」WebAppを実現するには:

Spring Bootアプリケーションを「従来のWAR」としてデプロイするには、アプリケーションクラスでSpringBootServletInitializerを拡張する必要があります。

注: SpringBootServletInitializerは、Servlet 3.0+仕様を参照するweb.xmlの「プログラムによる実装」であり、WebApplicationInitializerの実装が必要です。

したがって、SpringBootApplicationは、そのアプリケーションクラスが(SpringBootServletInitializerを拡張した後)
-@ WebFilter、
-@WebListenerおよび
-@ WebServletをスキャンするため、「web.xml」を必要としません。

アノテーション@ServletComponentScan

この注釈により、@ WebFilter、@ WebListener、および@WebServletで注釈が付けられたWebコンポーネントの基本パッケージをスキャンできます。

埋め込みコンテナーは@ WebServlet、@ WebFilter、および@WebListenerアノテーションをサポートしていないため、Spring Bootは埋め込みコンテナーに大きく依存して、これらの3つのアノテーションを使用するいくつかの依存jarをサポートするためにこの新しいアノテーション@ServletComponentScanを導入しました。

スキャンは、埋め込みサーブレットコンテナを使用する場合にのみ実行されます。

以下は私のSpring Boot Application Class Definitionです:-

ここに画像の説明を入力してください

カスタムサーブレット初期化子:-

ここで:Class:SpringBootServletInitializerを拡張するカスタムクラス「ServletInitializer」を定義しました。

前に説明したように、SpringBootServletInitializerはアノテーションのスキャンを担当します:
--@ WebFilter、
-@WebListener、および
-@WebServlet。

したがって、Spring Boot Application Classは

  • クラスを拡張する:SpringBootServletInitializer OR
  • クラスを拡張する拡張カスタムクラス: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
Steve Buzonas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.