Spring boot 使用自定义过滤器使@ControllerAdvice工作

Spring boot 使用自定义过滤器使@ControllerAdvice工作,spring-boot,authentication,exception,filter,spring-security,Spring Boot,Authentication,Exception,Filter,Spring Security,由于各种原因,我有一个现有的GlobalExceptionHandler来抛出4xx错误 我必须创建一个用于身份验证的筛选器(使用AbstractPreAuthenticatedProcessingFilter)。在创建筛选器之前,ExceptionHandler为不正确的HTTP方法、谓词、参数等提供了预期的异常。但在添加筛选器之后,在自定义身份验证筛选器之前不会调用异常处理程序 我曾尝试实现HandlerExceptionResolver并将其添加到过滤器链中,但只得到5xx错误 WebSe

由于各种原因,我有一个现有的
GlobalExceptionHandler
来抛出
4xx
错误

我必须创建一个用于身份验证的筛选器(使用
AbstractPreAuthenticatedProcessingFilter
)。在创建筛选器之前,
ExceptionHandler
为不正确的HTTP方法、谓词、参数等提供了预期的异常。但在添加筛选器之后,在自定义身份验证筛选器之前不会调用异常处理程序

我曾尝试实现
HandlerExceptionResolver
并将其添加到过滤器链中,但只得到
5xx
错误

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
@Order(1000)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {  
    @Autowired
    private FilterChainExceptionHandler filterChainExceptionHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .antMatcher("/**")
                .addFilterBefore(filterChainExceptionHandler, AbstractPreAuthenticatedProcessingFilter.class)
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .httpBasic();
    }

    @Bean
    public CustomFilter customFilter() throws Exception {
        CustomFilter customFilter = new CustomFilter();
        customFilter.setAuthenticationManager(authenticationManagerBean());
        return customFilter;
    }
注意:
CustomFilter
是用于验证标题值的验证过滤器

CustomFilter.java

@Component
@Order(2000)
public class CustomFilter extends AbstractPreAuthenticatedProcessingFilter {

... business logic
} 
@Component
@Order(500)
public class FilterChainExceptionHandler extends OncePerRequestFilter {


    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver resolver;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {


        try {
            filterChain.doFilter(request, response);
        } catch (Exception e) {
          // catch(MethodArgumentNotValidException e) // Adding this does not pass to GlobalExceptionHandler 
            // Throws 500 for all request
            resolver.resolveException(request, response, null, e); // Runtime exception
        }
    }
}
FilterChainExceptionHandler.java

@Component
@Order(2000)
public class CustomFilter extends AbstractPreAuthenticatedProcessingFilter {

... business logic
} 
@Component
@Order(500)
public class FilterChainExceptionHandler extends OncePerRequestFilter {


    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver resolver;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {


        try {
            filterChain.doFilter(request, response);
        } catch (Exception e) {
          // catch(MethodArgumentNotValidException e) // Adding this does not pass to GlobalExceptionHandler 
            // Throws 500 for all request
            resolver.resolveException(request, response, null, e); // Runtime exception
        }
    }
}
GlobalExceptionHandler
:根据请求头、参数、HTTP方法等抛出400个错误

@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class GlobalEceptionHandler {

@ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorDTO> handleMethodArgumentNotValidException(
            MethodArgumentNotValidException methodArgumentNotValidException) {

        BindingResult result = methodArgumentNotValidException.getBindingResult();

        ErrorDTO errors = getErrorDTO(result);

        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
    }
}
@顺序(有序。最高优先级)
@控制器建议
公共类GlobalEceptionHandler{
@ExceptionHandler(MethodArgumentNotValidException.class)
公共响应处理方法无效异常(
方法ArgumentNotValidException方法ArgumentNotValidException){
BindingResult=methodArgumentNotValidException.getBindingResult();
ErrorDTO errors=getErrorDTO(结果);
返回新的响应属性(错误,HttpStatus.BAD_请求);
}
}