我们如何在 HandlerInterceptorAdapter 中 postHandle 异常?
Posted
技术标签:
【中文标题】我们如何在 HandlerInterceptorAdapter 中 postHandle 异常?【英文标题】:How can we postHandle an exception in HandlerInterceptorAdapter? 【发布时间】:2020-10-09 14:41:42 【问题描述】:我目前正在尝试为 Spring Boot 实现一个自定义的错误处理程序,我已经完成了以下操作:
public class ExceptionHandler extends HandlerInterceptorAdapter
public static Logger log = LoggerFactory.getLogger(LoggingInterceptor.class);
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception
try
log.info("Service Calling on finished with status ",request.getRemoteUser(), request.getMethod(), request.getRequestURI(), HttpStatus.valueOf(response.getStatus()));
catch (Exception e)
// Do nothing
finally
log.error("[Spring Boot Interceptor] returned with ", handler, HttpStatus.valueOf(response.getStatus()));
不知何故这不起作用,并且仍然向客户端抛出异常,是否有某种方法可以捕获方法抛出的异常并忽略它。例如。
【问题讨论】:
你应该注册你的拦截器到注册表,检查这个***.com/questions/31082981/… 我添加了拦截器,它被执行了,但是在 postHandle 中定义的 try catch 不知何故没有处理异常(500 Internal Server Error),而是在控制台中抛出它。 我认为您需要在 afterComplete 方法中而不是在 postHandle 中处理异常。 请参考下面的帖子。 ***.com/questions/48785878/… 【参考方案1】:管理异常的好方法是使用@ControllerAdvice
,使用它您可以处理任何类型的异常并根据需要自定义响应。
正如评论中所说,你必须添加InterceptorRegistry
才能注册拦截器。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer
@Override
public void addInterceptors(InterceptorRegistry registry)
registry.addInterceptor(new Interceptor()).addPathPatterns("/**");
postHandle内的catch块只有在try-catch块内发生异常时才会执行,如下所示,
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception
try
int error = 1/0;
catch (Exception e)
log.info("Exception will be handled inside catch block");
现在让我们探索 @ControllerAdvice 来管理应用程序中的异常。这两个 API 会产生异常,我们将使用 @ExceptionHandler
管理异常
@GetMapping("/exception/404")
public void generateResourceNotFound()
throw new ResourceNotFoundException("resource not found");
@GetMapping("/exception/403")
public void generateAccessDenied()
throw new AccessDeniedException("access denied");
GlobalExceptionHandler.java
import com.learning.annotations.controller.ResourceNotFoundException;
import com.learning.annotations.dto.ErrorResponseDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler
public Logger log = LoggerFactory.getLogger(Interceptor.class);
@ExceptionHandler(AccessDeniedException.class)
public ResponseEntity<ErrorResponseDTO> handleAccessDeniedException(AccessDeniedException ex, WebRequest request)
ErrorResponseDTO response = new ErrorResponseDTO();
response.setError(ex.getMessage());
response.setMessage("You don't have authority to access the resource");
return new ResponseEntity<>(response, HttpStatus.FORBIDDEN);
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponseDTO> handleResourceNotFoundException(ResourceNotFoundException ex, WebRequest request)
ErrorResponseDTO response = new ErrorResponseDTO();
response.setError(ex.getMessage());
response.setMessage("Resource might be moved temporary or not available");
return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
要自定义响应,我们可以创建错误响应 DTO,如下所示,
import lombok.Data;
@Data
public class ErrorResponseDTO
private String message;
private String error;
【讨论】:
此解决方案有效,但 Boinix1441 询问他是否可以在响应中捕获应用程序在 rest 调用时抛出的异常。不在 postHandle 中抛出异常,在 postHandle 中处理。以上是关于我们如何在 HandlerInterceptorAdapter 中 postHandle 异常?的主要内容,如果未能解决你的问题,请参考以下文章
async/await 抛出 NullReferenceException 我们如何诊断我们在哪里搞砸了?