Spring MVC — обработка исключений
Приведу несколько примеров перехвата исключений с помощью Spring MVC.
Кусок кода из прошлой заметки про загрузку файла, но с дополнительным указанием возможных исключений:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST) @ResponseBody public ModelAndView uploadFile(@ModelAttribute("uploadedFile") UploadedFile uploadedFile, BindingResult result) throws IOException, BadFileNameException { ModelAndView modelAndView = new ModelAndView(); String fileName = null; MultipartFile file = uploadedFile.getFile(); fileValidator.validate(uploadedFile, result); //.... throw new IOException("Folder not found!"); // throw new MyFileUploadException("Bad filename:" + fileName); //... } |
В коде специально выбрасывается IOException или же созданное разработчиком какое-либо своё исключение MyFileUploadException.
Посмотрим как их можно обрабатывать:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "IOException exception! check arguments!") @ExceptionHandler(value ={IOException.class, SomeSecondException.class}) public void handleIOException() { logger.error("IOException handler executed"); } @ExceptionHandler(MyFileUploadException.class) public ModelAndView handleBadFileNameException(Exception ex) { logger.error("IOException handler executed"); ModelAndView modelAndView = new ModelAndView("error"); modelAndView.addObject("error", ex.getMessage()); return modelAndView; } |
Как видите можно указывать несколько исключений в одном методе. Во втором случае, при перехвате собственного исключения, происходит перенаправление на страницу error.jsp
1 2 3 4 5 6 7 8 9 10 11 12 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h3>${error}</h3> </body> </html> |
Пример кода собственного исключения:
1 2 3 4 5 6 7 8 9 10 11 12 |
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Bad filename") @SuppressWarnings("serial") public class MyFileUploadException extends Exception { public MyFileUploadException() { } public MyFileUploadException(String message) { super(message); } } |
Еще одна интересная возможность Spring — возможность создать глобальный перехватчик исключений. Он будет перехватывать исключения, которые не указаны в контроллере. Необходимо указать аннотацию @ControllerAdvice (см. AOP (советы) )
1 2 3 4 5 6 7 8 9 10 11 |
@ControllerAdvice public class GlobalExceptionHandler { private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); @ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "IOException occured") @ExceptionHandler(IOException.class) public void handleIOException() { logger.error("IOException handler executed"); } } |
В случае, если в контроллере исключение не было обработано, то следующим в очереди будет глобальный перехватчик исключений.
Третий вариант это реализация интерфейса
HandlerExceptionResolver.
Реализация похожа на предыдущий пример с использованием советов, но необходимо будет переопределить нужные методы.