2016-07-19 25 views
0

Ich versuche, einen WebFilter in meiner Feder-Anwendung hinzuzufügen. Ich verwende jedoch keine .xml-Dateien (nicht einmal eine web.xml, da meine Anwendung sie nicht benötigt).Spring WebFilter Mapping

Also, habe ich zu meiner Klasse, die AbstractAnnotationConfigDispatcherServletInitializer erweitert:

@Override 
protected Filter[] getServletFilters() { 
    return new Filter[]{new RequestFilter()}; 
} 

Und mein RequestFilter.java:

@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() { } 

Ich erwarte, dass nur Anfragen passende /test/* Muster gefiltert werden, aber Eine Anfrage an eine Ressource wird gefiltert.

Wie kann ich meinen Filter zuordnen?

Danke.

Antwort

0

@WebFilter - ist keine Spring Annotation. Der Frühling ignoriert es. Die Methode getServletFilters gibt ein Array von Filtern zurück, ohne sie URLs zuzuordnen. Also haben sie bei jeder Anfrage ausgelöst. Wenn Sie keine URL-Mappings in web.xml schreiben möchten, können Sie HandlerInterceptor anstelle von Filter verwenden. Sie können in der DispatcherServletInitializer abgebildet programmatisch werden:

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

Oder Sie können Sie Anmerkung besitzen WebFilter definieren!

Zuerst müssen Sie Utility-Klasse für passende URL-Muster:

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

Annotation selbst:

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
public @interface WebFilter { 
    String[] urlPatterns(); 
} 

Pass-Through-Funktionalität von URL Pattern-Matching:

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

Interceptor :

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

Und eine kleine Änderung in Zusammenhang Konfiguration:

<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> 
+0

Danke, Sergej. Ich habe diesen Thread komplett vergessen. Aber am Ende habe ich die Abfangjäger benutzt. Um nur ein Register zu erstellen, kann bei Verwendung von Spring-Sicherheit auch ein Filter in ein SecurityFilterChain eingefügt werden, das im HttpSecurity-Objekt enthalten ist. –