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_请求);
}
}