Различные варианты обработки исключений в Spring

Java задняя часть Spring

1. Введение

Важность унифицированной обработки исключений для приложений очевидна. Сегодня мы представимSpringкак унифицироватьRestОбработка исключений. В то же время мы также кратко сравним плюсы и минусы между ними.

2. @Controller в сочетании с @ExceptionHandler

объявить метод в контроллере и использовать@ExceptionHandlerТеги аннотаций могут быть:

 @Controller
 @RequestMapping("/test")
 public class TestController {
  
     @RequestMapping("/err")
     @ResponseBody
     public Object demo1(){
         int i = 1 / 0;
         return new Date();
     }
  
     @ExceptionHandler({RuntimeException.class})
     public ModelAndView fix(Exception ex){
         System.out.println(ex.getMessage());
         return new ModelAndView("error",new ModelMap("ex",ex.getMessage()));
     }
 }

преимущество:

  • наивысший приоритет.
  • @ExceptionHandlerОтмеченные типы возвращаемых значений метода поддерживают несколько типов. Может быть вид илиjsonЖдать.

недостаток:

  • ОдинControllerсередина@ExceptionHandlerТипы исключений в аннотации не могут отображаться одинаково, иначе во время выполнения будет создано исключение.
  • Требуется явное объявление типа исключения для обработки.
  • Область применения - это толькоControllerНе совсем глобальное исключение. Если вы хотите использовать его глобально, вам нужно поместить его в родительский класс всех контроллеров.

3. @ControllerAdvice в сочетании с @ExceptionHandler

Это2.Улучшенная версия , по определению@ControllerAdviceкласс и отметка на методе@ExceptionHandler, чтобы достичь цели глобальной обработки исключений:

 @ControllerAdvice
 public class TestController {
 
  
     @ExceptionHandler({RuntimeException.class})
     public ModelAndView fix(Exception ex){
         System.out.println(ex.getMessage());
         return new ModelAndView("error",new ModelMap("ex",ex.getMessage()));
     }
 }

преимущество:

  • Глобальная обработка исключений.
  • Полный контроль над телом ответа и кодом состояния
  • Сопоставляет несколько исключений с одним и тем же методом для совместной обработки и использует преимущества обновленногоRestful ResponseEntityотклик

недостаток:

  • ОдинControllerсередина@ExceptionHandlerТипы исключений в аннотации не могут отображаться одинаково, иначе во время выполнения будет создано исключение.
  • Требуется явное объявление типа исключения для обработки.

Как правило, этот метод также рекомендуется использовать для обработки исключений. Совместимость в большинстве случаев.

4. Интерфейс HandlerExceptionResolver

выполнитьHandlerExceptionResolverИнтерфейс, здесь мы наследуем его абстрактную реализациюAbstractHandlerExceptionResolver :

 @Component
 public class RestResponseStatusExceptionResolver extends AbstractHandlerExceptionResolver {
  
     @Override
     protected ModelAndView doResolveException(
       HttpServletRequest request, 
       HttpServletResponse response, 
       Object handler, 
       Exception ex) {
         try {
             if (ex instanceof IllegalArgumentException) {
                 return handleIllegalArgument((IllegalArgumentException) ex, response, handler);
             }
            //todo more exception
         } catch (Exception handlerException) {
               //todo 
         }
         return null;
     }
  
     private ModelAndView 
       handleIllegalArgument(IllegalArgumentException ex, HttpServletResponse response) 
       throws IOException {
         response.sendError(HttpServletResponse.SC_CONFLICT);
         String accept = request.getHeader(HttpHeaders.ACCEPT);
           //todo  more  response
         return new ModelAndView();
     }
 }

преимущество:

  • Это глобальный обработчик исключений.
  • Таким образом, глобальная обработка исключений возвращаетJSP,velocityУдобнее дождаться просмотра шаблона.
  • Поддерживаются несколько форматов ответов, хотя переопределенный метод возвращаетModelAndViewНо поскольку параметр имеетHttpServletResponse, мы можем использовать его для настройки результатов ответа. Например, если клиент запрашивает вводapplication / json, то в случае возникновения ошибки мы хотим убедиться, что возвращаемapplication / jsonЗакодированный ответ.

недостаток:

  • Нам нужно связаться с низкоуровневымHttpServletResponseВзаимодействие может реализовывать различные формы тел реагирования.
  • более низкий приоритет

5. Обработка исключений в Spring Boot

Если ваш фреймворкSpring Boot. Мы также можем использовать его уникальную обработку. Преимущество в том, что низкоуровневый API экранирован, а также очевиден недостаток, который не может ловить конкретные исключения.

5.1 Реализация ErrorController

Spring BootПо умолчанию предусмотрено/errormap для обработки всех ошибок, вServletВ контейнере прописана глобальная страница ошибки (Whitelabel Error Page) и вернуться к клиенту. путем реализацииErrorControllerинтерфейс и зарегистрирован какBean. Здесь больше нет примеров. Может относиться кBasicErrorController.

5.2 ДобавитьErrorAttributes

Мы также можем добавитьErrorAttributesТипBeanчтобы заменить обработку исключений по умолчанию.

 @Component
 public class MyCustomErrorAttributes extends DefaultErrorAttributes {
  
     @Override
     public Map<String, Object> getErrorAttributes(
       WebRequest webRequest, boolean includeStackTrace) {
         Map<String, Object> errorAttributes = 
           super.getErrorAttributes(webRequest, includeStackTrace);
         errorAttributes.put("locale", webRequest.getLocale()
             .toString());
         errorAttributes.remove("error");
  
         //todo your business
  
         return errorAttributes;
     }
 }

5.3 Наследование базового класса BasicErrorController

Spring BootАвтоконфигурация также обеспечивает реализациюErrorControllerБазовый класс для обработки исключений интерфейсаBasicErrorController, по умолчанию обрабатываетсяtext/htmlОшибка запроса типа, вы можете наследовать этот базовый класс для обработки большего количества типов запросов, добавлять общедоступные методы и использовать@RequestMappingаннотированныйproduceСвойство указывает тип обработки.

 @Component
 public class MyErrorController extends BasicErrorController {
  
     public MyErrorController(ErrorAttributes errorAttributes) {
         super(errorAttributes, new ErrorProperties());
     }
  
     @RequestMapping(produces = MediaType.APPLICATION_XML_VALUE)
     public ResponseEntity<Map<String, Object>> xmlError(HttpServletRequest request) {
          
     //todo your business
  
     }
 }

6. Исключение ResponseStatusException в Spring 5

Также в последнемSpring 5в вы также можете броситьResponseStatusExceptionисключение для обработки.

выгода:

  • удобнее в использовании
  • Один тип, много кодов состояния: Один тип исключения может вызвать много разных ответов. Это уменьшает тесную связь по сравнению с @ExceptionHandler.
  • Нам не нужно будет создавать столько пользовательских классов исключений
  • Улучшенный контроль над обработкой исключений, поскольку исключения можно создавать программно.

недостаток:

  • Без унифицированного способа обработки исключений сложнее обеспечить выполнение определенных общеприложенных соглашений.
  • Может быть много повторяющегося кода.

7. Резюме

Наши обычные и редкиеSpringСуммируются способы обработки исключений и анализируются преимущества и недостатки. Я верю, что вы можете найти способ справиться с этим, который вам подходит. Если это полезно для вас, пожалуйста, помогите поставить лайк, ваше поощрение, моя мотивация!

关注公众号:Felordcn获取更多资讯

Личный блог: https://felord.cn