如何管理 Spring 过滤器中抛出的异常? [英] How to manage exceptions thrown in filters in Spring?
问题描述
我想使用通用方式来管理 5xx 错误代码,让我们具体说一下当整个 Spring 应用程序中 db 关闭时的情况.我想要一个漂亮的错误 json 而不是堆栈跟踪.
I want to use generic way to manage 5xx error codes, let's say specifically the case when the db is down across my whole spring application. I want a pretty error json instead of a stack trace.
对于控制器,我有一个用于不同异常的 @ControllerAdvice
类,这也捕获了数据库在请求中间停止的情况.但这并不是全部.我也碰巧有一个自定义 CorsFilter
扩展 OncePerRequestFilter
并且当我调用 doFilter
时,我得到 CannotGetJdbcConnectionException
和它不会由 @ControllerAdvice
管理.我在网上读了几件事,这让我更加困惑.
For the controllers I have a @ControllerAdvice
class for the different exceptions and this is also catching the case that the db is stopping in the middle of the request. But this is not all. I also happen to have a custom CorsFilter
extending OncePerRequestFilter
and there when i call doFilter
i get the CannotGetJdbcConnectionException
and it will not be managed by the @ControllerAdvice
. I read several things online that only made me more confused.
所以我有很多问题:
- 我需要实现自定义过滤器吗?我找到了
ExceptionTranslationFilter
但这只能处理AuthenticationException
或AccessDeniedException
. - 我想实现我自己的
HandlerExceptionResolver
,但这让我怀疑,我没有任何自定义异常要管理,一定有比这更明显的方法.我还尝试添加一个 try/catch 并调用HandlerExceptionResolver
的实现(应该足够好,我的异常没什么特别的)但这在响应中没有返回任何内容,我得到状态 200和一个空的身体.
- Do i need to implement a custom filter? I found the
ExceptionTranslationFilter
but this only handlesAuthenticationException
orAccessDeniedException
. - I thought of implementing my own
HandlerExceptionResolver
, but this made me doubt, I don't have any custom exception to manage, there must be a more obvious way than this. I also tried to add a try/catch and call an implementation of theHandlerExceptionResolver
(should be good enough, my exception is nothing special) but this is not returning anything in the response, i get a status 200 and an empty body.
有什么好的办法可以解决吗?谢谢
Is there any good way to deal with this? Thanks
推荐答案
所以这就是我所做的:
我在这里阅读了有关过滤器的基础知识,我发现我需要创建一个自定义过滤器将位于过滤器链中的第一个,并且将有一个 try catch 来捕获可能在那里发生的所有运行时异常.然后我需要手动创建 json 并将其放入响应中.
I read the basics about filters here and I figured out that I need to create a custom filter that will be first in the filter chain and will have a try catch to catch all runtime exceptions that might occur there. Then i need to create the json manually and put it in the response.
这是我的自定义过滤器:
So here is my custom filter:
public class ExceptionHandlerFilter extends OncePerRequestFilter {
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
filterChain.doFilter(request, response);
} catch (RuntimeException e) {
// custom error response class used across my project
ErrorResponse errorResponse = new ErrorResponse(e);
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
response.getWriter().write(convertObjectToJson(errorResponse));
}
}
public String convertObjectToJson(Object object) throws JsonProcessingException {
if (object == null) {
return null;
}
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(object);
}
}
然后我在 CorsFilter
之前将它添加到 web.xml 中.它有效!
And then i added it in the web.xml before the CorsFilter
. And it works!
<filter>
<filter-name>exceptionHandlerFilter</filter-name>
<filter-class>xx.xxxxxx.xxxxx.api.controllers.filters.ExceptionHandlerFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>exceptionHandlerFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这篇关于如何管理 Spring 过滤器中抛出的异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!