264

FilterSpring Boot にクラス (Web アプリケーション用)の注釈はありますか? おそらく@Filter

プロジェクトにカスタム フィルターを追加したいと考えています。

Spring Boot リファレンス ガイドでは について言及されて FilterRegistrationBeanいますが、その使用方法がわかりません。

4

24 に答える 24

174

サードパーティ フィルタをセットアップする場合は、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でテストされました。

于 2015-06-05T05:09:16.707 に答える
82

サーブレット フィルターを示す特別な注釈はありません。@BeanFilter(または) を宣言するだけFilterRegistrationBeanです。例 (すべての応答にカスタム ヘッダーを追加する) は、Boot 自身のEndpointWebMvcAutoConfigurationにあります。

a のみを宣言するFilterと、すべてのリクエストに適用されます。も追加するFilterRegistrationBeanと、適用する個々のサーブレットと URL パターンを追加で指定できます。

ノート:

Spring Boot 1.4 の時点でFilterRegistrationBeanは非推奨ではなく、単純にパッケージを からorg.springframework.boot.context.embedded.FilterRegistrationBeanに移動しましたorg.springframework.boot.web.servlet.FilterRegistrationBean

于 2013-11-07T08:17:35.163 に答える
15

Springのドキュメントから、

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

Servlet、Filter、または Servlet *Listener を追加するには、その@Bean 定義を提供します。

例えば:

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

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

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

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

于 2016-08-08T13:37:52.413 に答える
10

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);
    }
}
于 2019-07-27T07:46:10.827 に答える
4

このフィルターは、クロスオリジン アクセスを許可するのにも役立ちます

@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

    }

}
于 2019-07-24T12:50:34.270 に答える
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");
    }

}
于 2018-04-02T11:43:34.310 に答える
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 アプリケーションはそのままにしました。

于 2018-02-26T19:15:29.763 に答える
2

使用する:

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

}
于 2018-06-06T11:31:04.850 に答える
2

javax.servlet.Filter を実装するクラスで @WebFilter javax.servlet.annotation.WebFilter を使用できます。

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

次に @ServletComponentScan を使用して登録します。

于 2017-07-18T10:41:52.653 に答える
1

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

}
于 2018-06-13T05:55:32.013 に答える