Spring Boot中是否有Filter类(用于web应用程序)的注释?也许@Filter ?

我想在我的项目中添加一个自定义过滤器。

Spring Boot参考指南中提到过 FilterRegistrationBean,但我不确定如何使用它。


当前回答

我看到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 );
    }

}

其他回答

没有特殊的注释来表示servlet筛选器。您只需声明一个Filter类型的@Bean(或FilterRegistrationBean)。在Boot自己的EndpointWebMvcAutoConfiguration中有一个例子(为所有响应添加自定义头);

如果你只声明一个过滤器,它将被应用到所有的请求。如果您还添加了一个FilterRegistrationBean,您可以另外指定要应用的单个servlet和url模式。

注意:

从Spring Boot 1.4开始,FilterRegistrationBean不再弃用,而是简单地将包从org.springframework. Boot .context. embedd.filterregistrationbean移动到org.springframework.boot.web.servlet.FilterRegistrationBean

这是一个建议而不是答案,但如果你在你的web应用程序中使用Spring MVC,最好使用Spring HandlerInterceptor而不是Filter。

它可以做同样的工作,但是

可以使用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");
    }

}

下面是一个在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 {}

}

如果您想要设置一个第三方过滤器,您可以使用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:

@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测试的。

对于基于任何条件和spring引导中的任何列表的过滤,查询语言更加灵活,并允许我们向下过滤到我们需要的确切资源。 例如,如果我们有一个简单的实体,如User,并像这样定义它。

@Entity
public class User {
@Id
@GeneratedValue(strategy = 
GenerationType.AUTO)
private Long id;

private String firstName;
private String lastName;
private String email;

private int age;

//Setter and getter as usual

然后我们创建一个实现Specification接口的UserSpecification,我们将传递我们自己的约束来构造实际的查询。在本部分中,与标准和构建器相关的方法非常有用和灵活。

public class UserSpecification implements Specification<User> {

private SearchCriteria criteria;

@Override
public Predicate toPredicate
  (Root<User> root, CriteriaQuery<?> query, CriteriaBuilder builder) {

    if (criteria.getOperation().equalsIgnoreCase(">")) {
        return builder.greaterThanOrEqualTo(
          root.<String> get(criteria.getKey()), criteria.getValue().toString());
    } 
    else if (criteria.getOperation().equalsIgnoreCase("<")) {
        return builder.lessThanOrEqualTo(
          root.<String> get(criteria.getKey()), criteria.getValue().toString());
    } 
    else if (criteria.getOperation().equalsIgnoreCase(":")) {
        if (root.get(criteria.getKey()).getJavaType() == String.class) {
            return builder.like(
              root.<String>get(criteria.getKey()), "%" + criteria.getValue() + "%");
        } else {
            return builder.equal(root.get(criteria.getKey()), criteria.getValue());
        }
    }
    return null;
}
}

此外,我们还创建了一个基于以下SearchCriteria类中表示的一些简单约束的规范,任何条件都可以像这样创建:

public class SearchCriteria {
private String key;
private String operation;
private Object value;
 }

最后定义UserRepository和扩展JpaSpecificationExecutor,

public interface UserRepository 
extends JpaRepository<User, Long>, 
JpaSpecificationExecutor<User> {}