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

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

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


当前回答

如果您使用Spring Boot + Spring Security,则可以在安全配置中执行此操作。

在下面的示例中,我在UsernamePasswordAuthenticationFilter之前添加了一个自定义过滤器(请参阅所有默认的Spring安全过滤器及其顺序)。

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

其他回答

对于基于任何条件和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> {}

没有特殊的注释来表示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

在Spring文档中,

嵌入式servlet容器——向应用程序中添加servlet、过滤器或监听器

要添加Servlet、过滤器或Servlet *监听器,请提供@Bean 定义。

例如:

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

将这个@Bean配置添加到@Configuration类中,过滤器将在启动时注册。

此外,您还可以使用类路径扫描添加servlet、过滤器和侦听器,

@WebServlet, @WebFilter和@WebListener注释类可以是 自动注册到嵌入的servlet容器 用@ServletComponentScan和注释@Configuration类 指定包含所需组件的包 登记。默认情况下,@ServletComponentScan将从包中扫描 注释类的。

你主要需要两样东西:

Add @ServletComponentScan to your Main Class You may add a package named filter inside it. You create a Filter class that has the following: @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() { } }

过滤器主要用于日志文件中。它根据您在项目中使用的记录器而有所不同。

让我解释一下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 > INFO > WARN > ERROR > FATAL > OFF