Как зафиксировать все исключения Spring/Spring Boot 2.x?

Я создал приложение Spring boot 2.x, используя эту демонстрацию:

https://spring.io/guides/gs/spring-boot/

Проблема, с которой я сталкиваюсь, заключается в том, что при загрузке Spring/Spring возникает исключение, оно выводится на стандартный вывод. Я не хочу этого. Я хочу захватить их и выполнить другую обработку, например, зарегистрировать их. Я могу фиксировать исключения своего кода, но не могу фиксировать исключения загрузки Spring/Spring. Поэтому, как мне зафиксировать все исключения Spring/Spring Boot 2.x, чтобы я мог их обработать? Есть ли простой способ сделать это, например, общий перехватчик исключений? Может кто-нибудь показать мне код?

Мой код:

1. Пример.java

   package example;

   import org.springframework.boot.SpringApplication;
   import org.springframework.boot.autoconfigure.SpringBootApplication;
   import org.springframework.boot.builder.SpringApplicationBuilder;
   import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;


   @SpringBootApplication
   public class Example extends SpringBootServletInitializer {

     public static void main(String[] args) throws Exception {

       SpringApplication.run(Example.class, args);
      
     }
  
   }

2. ПримерКонтроллер.java

   package example;


   import org.springframework.stereotype.Controller;
   import org.springframework.http.HttpStatus;
   import org.springframework.ui.Model;
   import org.springframework.ui.ModelMap;
   import org.springframework.validation.BindingResult;

   import org.springframework.web.bind.annotation.GetMapping;
   import org.springframework.web.bind.annotation.PostMapping;
   import org.springframework.web.bind.annotation.RequestBody;
   import org.springframework.web.bind.annotation.RequestParam;
   import org.springframework.web.bind.annotation.ResponseStatus;
   import org.springframework.web.bind.annotation.ResponseBody;
   import org.springframework.web.bind.annotation.CrossOrigin;

   import org.springframework.web.bind.annotation.ModelAttribute;
   import org.springframework.web.servlet.ModelAndView;


   @Controller
   public class ExampleController {
  

     @GetMapping ("/example")
     public ModelAndView example()
     {
        MyData data= new MyData();
        data.setName("Example");
        data.setVersion("1.0");
    
        ModelAndView model = new ModelAndView("page");
        model.addObject("page", data);
     
       return model;
     }
            
   }

3. GeneralExceptionHandler.java

   package example;

   import org.springframework.web.bind.annotation.ControllerAdvice;
   import org.springframework.web.bind.annotation.ExceptionHandler;

   @ControllerAdvice
   class GeneralExceptionHandler {

    @ExceptionHandler(Exception.class)
    public void handleException() {
      
      System.out.println("Exception handler");
      
    }
   }

4. MyData.java

   package example;

   import lombok.Data;

   @Data
   public class MyData {
  
     private String name;
     private String version;
   }

5. страница.jsp

  <!DOCTYPE html>
  <%@ taglib prefix = "form" uri = "http://www.springframework.org/tags/form"%>

  <html> 

   <form:form id = "myForm" class = "form-horizontal" 
    modelAttribute = "page">
    <form:label id = "name" class = "control-label" path = "name" for = "name">
    ${page.name}</form:label>
    <!-- Error introduced on purpose to force exception. "version123" should be just "version" -->
    <form:label id = "version" class = "control-label" path = "version" for = "version">
    ${page.version123}</form:label>
   </form:form>
      
  </html>

пожалуйста, сообщите нам, что вы сделали, чтобы мы могли вам помочь

Abdelghani Roussi 16.03.2019 16:02

Файл page.jsp: <!DOCTYPE html> <%@ taglib prefix = "form" uri = "springframework.org/tags/form"%> <html> <form:form id = "myForm" class = "form-horizontal" modelAttribute = "page"> < form:label id = "name" class = "control-label" path = "name" for = "name"> ${page.name}</form:label> <!-- Ошибка введена специально для принудительного исключения. «версия123» должна быть просто «версией» --> <form:label id = "version" class = "control-label" path = "version" for = "version"> ${page.version123}</form:label > </форма:форма> </html>

code4u 16.03.2019 21:25

@AbdelghaniRoussi Не знаю, почему ваш ответ был удален. Вы видели код, который я разместил? Я попробовал предложенное вами решение, но оно не сработало. Любые другие идеи?

code4u 16.03.2019 21:27

@JBNizet Вы видели код, который я разместил? Я попробовал решение, но оно не сработало.

code4u 16.03.2019 21:28
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
5
5 848
2

Ответы 2

Вы можете использовать аннотацию @ExceptionHandler, чтобы поймать конкретное исключение, для этого вы можете просто аннотировать метод внутри вашего контроллера с помощью @ExceptionHandler и предоставить ему конкретное исключение, например:

@ExceptionHandler(DataIntegrityViolationException.class)
public void handleException(){
 // do some thing here
}

Ограничение этого способа заключается в том, что он будет обрабатывать только исключения, созданные @RequestMapping, где объявлен @ExceptionHandler. Чтобы избежать этого ограничения, вы можете использовать Совет контроллера, который позволяет вам использовать точно такие же методы обработки исключений, но применять их ко всему приложению, например, используя рекомендации контроллера:

@ControllerAdvice
class GeneralExceptionHandler {

    @ExceptionHandler(DataIntegrityViolationException.class)
    public void handleException() {
        // Do some thing here
    }
}

подсказка: если вы хотите перехватить все проверенные исключения, вы можете использовать @ExceptionHandler(Exception.class)

page.jsp Код: <!DOCTYPE html> <%@ taglib prefix = "form" uri = "springframework.org/tags/form"%> <html> <form:form id = "myForm" class = "form-horizontal" modelAttribute = "page"> < form:label id = "name" class = "control-label" path = "name" for = "name"> ${page.name}</form:label> <!-- Ошибка введена специально для принудительного исключения. «версия123» должна быть просто «версией» --> <form:label id = "version" class = "control-label" path = "version" for = "version"> ${page.version123}</form:label > </форма:форма> </html>

code4u 16.03.2019 18:56

Решение не работает. Смотрите код, который я разместил. Он по-прежнему выдает исключения загрузки Spring на стандартный вывод. К сожалению, код page.jsp был вырезан Stackoverflow, но идея понятна. – code4u 1 час назад

code4u 16.03.2019 20:20

Вы можете использовать АОП с pointcut для всех общедоступных методов в контроллере. Я использую BaseController в качестве базового класса для всех моих контроллеров.

@RestController
@RequestMapping(value = "/api/application")
public class ApllicationController extends ApiController {
   //class body with method
}

Затем добавьте АОП, обрабатывающий все исключения, вызываемые общедоступными методами в контроллере.

@Aspect
@Configuration
public class AOP_ApiController {

    @Pointcut("execution (public * *(..))")
    private void anyPublicMethod() {}

    @Pointcut("execution (* api.ApiController+.*(..))")//here package and class name as base class
    private void methodOfApiController() {}


    @AfterThrowing(value = "methodOfApiController() && anyPublicMethod()", throwing = "exception")
    public void afterThrowingExceptionFromApiController(JoinPoint joinPoint, Exception exception) throws Exception {
        ApiController controller = getController(joinPoint);
        String methodName=getMethodName(joinPoint);
        logException(exception, controller, methodName);
        throw exception;
    }

    private ApiController getController(JoinPoint joinPoint) {
        return (ApiController) joinPoint.getTarget();
    }

    private String getMethodName(JoinPoint joinPoint) {
        return joinPoint.getSignature().getName();
    }

    private void logException(Exception ufeException, ApiController controller, String methodName) {
        //log exception as you want
    }
}

Другие вопросы по теме