首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >弹簧WebFilter映射

弹簧WebFilter映射
EN

Stack Overflow用户
提问于 2016-07-19 18:05:57
回答 4查看 15.3K关注 0票数 3

我正试图在我的spring应用程序中添加一个WebFilter。但是,我不使用.xml文件(甚至不使用web.xml,因为我的应用程序不需要它)。

因此,我将扩展AbstractAnnotationConfigDispatcherServletInitializer的类添加到

代码语言:javascript
复制
@Override
protected Filter[] getServletFilters() {
    return new Filter[]{new RequestFilter()};
}

我的RequestFilter.java:

代码语言:javascript
复制
@WebFilter("/test/*")
public class RequestFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException { }

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException { }

@Override
public void destroy() { }

我希望只有匹配/test/*模式的请求才会被过滤,但是对任何资源的请求都会被过滤。

我怎样才能映射我的过滤器?

谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-04-07 09:36:26

@WebFilter -不是Spring注释。春天忽略了它。方法getServletFilters返回一个过滤器数组,而不将它们映射到URL。所以他们每次请求都会触发。如果不想在web.xml中编写url映射,可以使用HandlerInterceptor而不是Filter。可以在DispatcherServletInitializer中以编程方式映射它们。

代码语言:javascript
复制
public class SomeInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
        // ...
        return true;
    }
}

@Configuration
@ComponentScan("com.example")
@EnableWebMvc  
public class AppConfig extends WebMvcConfigurerAdapter  {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry
          .addInterceptor(new SomeInterceptor())
          .addPathPatterns("/test/*");
    }
}

public class WebAppInitializer implements WebApplicationInitializer {
    public void onStartup(ServletContext servletContext) throws ServletException {  
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();  
        ctx.register(AppConfig.class);  
        ctx.setServletContext(servletContext);    
        Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));  
        dynamic.addMapping("/");  
        dynamic.setLoadOnStartup(1);  
   }  
}

或者您可以定义自己的WebFilter注释!

首先,需要实用工具类来匹配URL模式:

代码语言:javascript
复制
public class GlobMatcher {
    public static boolean match(String pattern, String text) {
        String rest = null;
        int pos = pattern.indexOf('*');
        if (pos != -1) {
            rest = pattern.substring(pos + 1);
            pattern = pattern.substring(0, pos);
        }

        if (pattern.length() > text.length())
            return false;

        for (int i = 0; i < pattern.length(); i++)
            if (pattern.charAt(i) != '?' 
                    && !pattern.substring(i, i + 1).equalsIgnoreCase(text.substring(i, i + 1)))
                return false;

        if (rest == null) {
            return pattern.length() == text.length();
        } else {
            for (int i = pattern.length(); i <= text.length(); i++) {
                if (match(rest, text.substring(i)))
                    return true;
            }
            return false;
        }
    }
}

注释本身:

代码语言:javascript
复制
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface WebFilter {
    String[] urlPatterns();
}

URL模式匹配的传递功能:

代码语言:javascript
复制
@Aspect
public class WebFilterMatcher {
    @Pointcut("within(@com.example.WebFilter *)")
    public void beanAnnotatedWithWebFilter() {}

    @Pointcut("execution(boolean com.example..preHandle(..))")
    public void preHandleMethod() {}

    @Pointcut("preHandleMethod() && beanAnnotatedWithWebFilter()")
    public void preHandleMethodInsideAClassMarkedWithWebFilter() {}

    @Around("preHandleMethodInsideAClassMarkedWithWebFilter()")
    public Object beforeFilter(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        if(args.length > 0) {
            HttpServletRequest request = (HttpServletRequest) args[0];
            Class target = joinPoint.getTarget().getClass();
            if (target.isAnnotationPresent(WebFilter.class)) {
                String[] patterns = ((WebFilter) target.getAnnotation(WebFilter.class)).urlPatterns();
                for (String pattern : patterns) {
                    if (GlobMatcher.match(pattern, request.getRequestURI())) {
                        return joinPoint.proceed();
                    }
                }
            }
        }
        return true;
    }
}

拦截器:

代码语言:javascript
复制
@WebFilter(urlPatterns = {"/test/*"})
public class SomeInterceptor extends HandlerInterceptorAdapter { 
    @Override 
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
        // ...
        return true; 
    }
}

以及上下文配置中的一些变化:

代码语言:javascript
复制
<beans> <!-- Namespaces are omitted for brevity -->
  <aop:aspectj-autoproxy />

  <bean id="webFilterMatcher" class="com.example.WebFilterMatcher" />

  <mvc:interceptors>
    <bean class="com.example.SomeInterceptor" />
  </mvc:interceptors>
</beans>
票数 5
EN

Stack Overflow用户

发布于 2019-03-24 09:05:42

另一个选项是使用FilterRegistrationBean注册自定义过滤器类,而不是将过滤器本身添加为bean。示例:

代码语言:javascript
复制
@Bean
public FilterRegistrationBean<RequestResponseLoggingFilter> loggingFilter(){
    FilterRegistrationBean<RequestResponseLoggingFilter> registrationBean 
      = new FilterRegistrationBean<>();

    registrationBean.setFilter(new RequestResponseLoggingFilter());
    registrationBean.addUrlPatterns("/users/*");            
    return registrationBean;    
}

摘自:https://www.baeldung.com/spring-boot-add-filter

票数 2
EN

Stack Overflow用户

发布于 2018-05-22 07:04:15

如果使用Spring,可以将@Component添加到筛选器实现中,也可以将@ServletComponentScan添加到主类中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38465566

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档