Roh*_*ain 11 spring exception-handling spring-mvc
我使用@ExceptionHandler在spring中处理异常.使用@ExceptionHandler注释的方法捕获控制器抛出的任何异常,并相应地采取操作.为了避免为我使用@ControllerAdvice注释的每个控制器编写@exceptionHandler.
一切都按预期工作正常.
现在我有一个过滤器(是的,不是拦截器,以处理某些要求),它是使用DelegatingFilterProxy和ContextLoaderListener实现的.
当我从上面的过滤器中抛出相同的异常时,它没有像在控制器情况下那样完成.它直接抛给用户.
这里有什么问题?
And*_*and 18
过滤器在控制器被解析之前发生,因此控制器建议无法捕获从过滤器抛出的异常.
过滤器是servlet的一部分,而不是MVC堆栈.
Ric*_*ard 12
由于异常不是从控制器而是从过滤器引发的,@ControllerAdvice 不会捕获它。
因此,我在四处寻找后找到的最佳解决方案是为这个内部错误创建一个过滤器:
public class ExceptionHandlerFilter extends OncePerRequestFilter {
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
filterChain.doFilter(request, response);
} catch (JwtException e) {
setErrorResponse(HttpStatus.BAD_REQUEST, response, e);
e.printStackTrace();
} catch (RuntimeException e) {
e.printStackTrace();
setErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, response, e);
}
}
public void setErrorResponse(HttpStatus status, HttpServletResponse response, Throwable ex){
response.setStatus(status.value());
response.setContentType("application/json");
// A class used for errors
ApiError apiError = new ApiError(status, ex);
try {
String json = apiError.convertToJson();
System.out.println(json);
response.getWriter().write(json);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
将其添加到您的配置中,我正在使用 WebSecurityConfigurerAdapter 实现:
// Custom JWT based security filter
httpSecurity
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
// Custom Exception Filter for filter
httpSecurity
.addFilterBefore(exceptionHandlerFilterBean(), JwtAuthenticationTokenFilter.class);
Run Code Online (Sandbox Code Playgroud)
错误类:
public class ApiError {
private HttpStatus status;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
private LocalDateTime timestamp;
private String message;
private String debugMessage;
private ApiError() {
timestamp = LocalDateTime.now();
}
public ApiError(HttpStatus status) {
this();
this.status = status;
}
public ApiError(HttpStatus status, Throwable ex) {
this();
this.status = status;
this.message = "Unexpected error";
this.debugMessage = ex.getLocalizedMessage();
}
public ApiError(HttpStatus status, String message, Throwable ex) {
this();
this.status = status;
this.message = message;
this.debugMessage = ex.getLocalizedMessage();
}
public String convertToJson() throws JsonProcessingException {
if (this == null) {
return null;
}
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
return mapper.writeValueAsString(this);
}
//Setters and getters
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14417 次 |
| 最近记录: |