首页 > 解决方案 > 如何捕获 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.example.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.ExampleController.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>

标签: javaspringspring-bootexception

解决方案


您可以使用@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)


推荐阅读