Spring Boot(mvc)中是否可以 记录自定义异常并将其抛出,而其堆栈跟踪在日志 文件中 不可见 ?但是对于其他任何异常,仍然请参见堆栈跟踪。
详细说明:
我正在使用Spring Boot创建一个简单的Rest服务。 我喜欢针对自定义异常,默认情况下日志中没有堆栈跟踪, 并且使用基本异常详细信息(状态,错误,消息)创建了json响应。
问题在于 它也根本不创建任何日志 条目,因此我将不得不手动执行此操作:
自订例外
@ResponseStatus(value = HttpStatus.CONFLICT) public class DuplicateFoundException extends RuntimeException { public DuplicateFoundException(String message) { super(message); } }
服务方法中引发异常(@RestController中)
if (!voteDao.findByItemAndUser(item, voteDto.getUserId()).isEmpty()) { log.warn("... already voted ..."); //TODO: don't do this for every throw throw new DuplicateFoundException("... already voted ..."); }
具有更多的异常会导致在每次抛出之前放置log语句,这是我认为的一种不好的方法。我尝试从服务方法中删除所有日志语句,并创建了 @ControlledAdvice,在其中记录所有自定义异常 并重新抛出它们,因此我仍然像以前一样得到漂亮的json:
@ControllerAdvice public class RestExceptionHandler { private static final Logger log = Logger.getLogger(RestExceptionHandler.class); @ExceptionHandler public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception { if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) { log.warn(e.getMessage()); } else { log.error("..."); } throw e; } }
现在的问题是,我不仅看到日志条目,还看到自定义异常的堆栈跟踪, 并且找不到解决该问题的方法。我认为问题是由再次抛出引起的。一个可能的解决方案是为异常创建一个自定义类,我将返回该类,但是我不喜欢这种想法,因为异常编组似乎可以正常工作。
有什么提示吗?谢谢。
解决方案是 将异常处理留给spring boot ,以便默认情况下不记录自定义异常,而记录其他异常。我从其余控制器中删除了@ControllerAdvice以及日志记录语句, 并将日志记录语句添加到自定义异常构造函数中 。
public DuplicateFoundException(String message) { super(message); LOGGER.warn(message); }
我不确定这是否是最好的方法,但是现在我仅在一个地方进行了自定义异常日志记录,而不必为每个异常重复log语句,也不必在日志中查看其堆栈跟踪或任何其他错误消息。