美文网首页
报错:Cannot register after unregis

报错:Cannot register after unregis

作者: 晨暮时代 | 来源:发表于2019-05-15 11:48 被阅读0次

    因为对springsecurity不熟悉,在配置过滤器的时候报出了如题所示的错误,对应的代码如下:

        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable() 
            .exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
         .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
         .and().authorizeRequests()
         .antMatchers("/login", "/project", "/fund").permitAll()
         .anyRequest().authenticated()
         // 产生错误的代码
         .and().addFilterBefore(new JwtLoginFilter(jwtUserDetailService, jwtTokenUtil), OncePerRequestFilter.class);
            http.headers().frameOptions().sameOrigin()
                    .cacheControl();
        }
    

    错就错在addFilterBefore那里,我不应该用OncePerRequestFilter.class作为第二个参数。点进addFilterBefore查看内部源码:

     public HttpSecurity addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter) {
            this.comparator.registerBefore(filter.getClass(), beforeFilter);
            return this.addFilter(filter);
        }
    

    再看registerBefore的源码:

    public void registerBefore(Class<? extends Filter> filter, Class<? extends Filter> beforeFilter) {
            Integer position = this.getOrder(beforeFilter);
            if (position == null) {
                throw new IllegalArgumentException("Cannot register after unregistered Filter " + beforeFilter);
            } else {
                this.put(filter, position - 1);
            }
        }
    

    发现报错原因是由于position == null。再点getOrder进去看看:

    private Integer getOrder(Class<?> clazz) {
        while(clazz != null) {
            // 查找XXXFilter.class所在的位置
            Integer result = (Integer)this.filterToOrder.get(clazz.getName());
            if (result != null) {
                return result;
            }
    
            clazz = clazz.getSuperclass();
        }
    
        return null;
    }
    

    可以看到,filterToOrder是一个Map,其预先put了固定的若干个过滤器类,它会试图去查找XXXFilter.class,但是没有找到,所以为null。addFilterBefore的作用就是将我们自定义的过滤器根据XXXFilter.class所在filterToOrder中的位置,是插在它的前面还是它的后面。

    相关文章

      网友评论

          本文标题:报错:Cannot register after unregis

          本文链接:https://www.haomeiwen.com/subject/fafpaqtx.html