Spring propose trois façons de gérer les exceptions unifiées, à savoir :
en utilisant l'annotation @ExceptionHandler, en implémentant l'interface HandlerExceptionResolver et en utilisant l'annotation @controlleradvice
Utiliser l'annotation @ExceptionHandler
Un inconvénient de l'utilisation de cette annotation est que la méthode de gestion des exceptions doit être dans le même contrôleur que la méthode qui a provoqué l'erreur. Utilisez comme suit :
@Controller public class GlobalController { /** * 用于处理异常的 * @return */ @ExceptionHandler({MyException.class}) public String exception(MyException e) { System.out.println(e.getMessage()); e.printStackTrace(); return "exception"; } @RequestMapping("test") public void test() { throw new MyException("出错了!"); } }
Comme vous pouvez le constater, le plus gros défaut de cette méthode est qu'elle ne peut pas contrôler globalement les exceptions. Chaque classe doit être écrite une fois.
Implémentez l'interface HandlerExceptionResolver
Cette méthode permet un contrôle global des exceptions. Par exemple :
@Component public class ExceptionTest implements HandlerExceptionResolver{ /** * TODO 简单描述该方法的实现功能(可选). * @see org.springframework.web.servlet.HandlerExceptionResolver#resolveException(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception) */ public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { System.out.println("This is exception handler method!"); return null; } }
Utiliser @ControllerAdvice+ @ExceptionHandler annotation
Comme mentionné ci-dessus, la méthode @ExceptionHandler qui nécessite la gestion des exceptions doit se trouver dans le même contrôleur que la méthode qui a provoqué l'erreur. Ensuite, lorsque le code ajoute @ControllerAdvice, il n'est pas nécessaire qu'il se trouve dans le même contrôleur. Il s'agit également d'une nouvelle fonctionnalité apportée par Spring 3.2. Comme son nom l’indique, cela signifie généralement une amélioration du contrôleur. En d'autres termes, @controlleradvice + @ExceptionHandler peut également réaliser une capture globale des exceptions.
Veuillez vous assurer que cette classe WebExceptionHandle peut être analysée et chargée dans le conteneur Spring.
@ControllerAdvice @ResponseBody public class WebExceptionHandle { private static Logger logger = LoggerFactory.getLogger(WebExceptionHandle.class); /** * 400 - Bad Request */ @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(HttpMessageNotReadableException.class) public ServiceResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { logger.error("参数解析失败", e); return ServiceResponseHandle.failed("could_not_read_json"); } /** * 405 - Method Not Allowed */ @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) @ExceptionHandler(HttpRequestMethodNotSupportedException.class) public ServiceResponse handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) { logger.error("不支持当前请求方法", e); return ServiceResponseHandle.failed("request_method_not_supported"); } /** * 415 - Unsupported Media Type */ @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE) @ExceptionHandler(HttpMediaTypeNotSupportedException.class) public ServiceResponse handleHttpMediaTypeNotSupportedException(Exception e) { logger.error("不支持当前媒体类型", e); return ServiceResponseHandle.failed("content_type_not_supported"); } /** * 500 - Internal Server Error */ @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(Exception.class) public ServiceResponse handleException(Exception e) { if (e instanceof BusinessException){ return ServiceResponseHandle.failed("BUSINESS_ERROR", e.getMessage()); } logger.error("服务运行异常", e); e.printStackTrace(); return ServiceResponseHandle.failed("server_error"); } }
Si le type d'exception à gérer n'est pas déclaré dans l'annotation @ExceptionHandler, il est par défaut le type d'exception dans la liste des paramètres. Cela peut donc aussi s'écrire comme ceci :
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler() @ResponseBody String handleException(Exception e){ return "Exception Deal! " + e.getMessage(); } }
L'objet paramètre est l'objet d'exception lancé par la couche Contrôleur !
Héritez de la classe ResponseEntityExceptionHandler pour implémenter la capture globale des exceptions pour l'interface Rest et pouvez renvoyer un format personnalisé :
@Slf4j @ControllerAdvice public class ExceptionHandlerBean extends ResponseEntityExceptionHandler { /** * 数据找不到异常 * @param ex * @param request * @return * @throws IOException */ @ExceptionHandler({DataNotFoundException.class}) public ResponseEntity<Object> handleDataNotFoundException(RuntimeException ex, WebRequest request) throws IOException { return getResponseEntity(ex,request,ReturnStatusCode.DataNotFoundException); } /** * 根据各种异常构建 ResponseEntity 实体. 服务于以上各种异常 * @param ex * @param request * @param specificException * @return */ private ResponseEntity<Object> getResponseEntity(RuntimeException ex, WebRequest request, ReturnStatusCode specificException) { ReturnTemplate returnTemplate = new ReturnTemplate(); returnTemplate.setStatusCode(specificException); returnTemplate.setErrorMsg(ex.getMessage()); return handleExceptionInternal(ex, returnTemplate, new HttpHeaders(), HttpStatus.OK, request); } }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!