如何捕获Spring / Spring Boot 2.x的所有异常?

时间:2019-03-16 14:52:04

标签: java spring spring-boot exception

我使用此演示构建了自己的Spring boot 2.x应用程序:https://spring.io/guides/gs/spring-boot/我遇到的问题是,当Spring / Spring boot中出现异常时,它会打印到标准输出中。我不要我想捕获它们并进行其他处理,例如记录它们。我可以捕获代码异常,但不能捕获Spring / Spring引导异常。因此,如何捕获Spring / Spring Boot 2.x的所有异常,以便能够处理它们?有没有像通用异常捕获器这样的简单方法?有人可以告诉我一些代码吗?

我的代码:

  1. Example.java

    包装示例;

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

    @SpringBootApplication 公共类示例扩展SpringBootServletInitializer {

    公共静态void main(String [] args)引发异常{

    SpringApplication.run(Example.class, args);
    

    }

    }

  2. ExampleController.java

    包装示例;

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

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

    导入org.springframework.web.bind.annotation.ModelAttribute; 导入org.springframework.web.servlet.ModelAndView;

    @控制器 公共类ExampleController {

    @GetMapping(“ /示例”)   公共ModelAndView示例()   {     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

    包装示例;

    导入org.springframework.web.bind.annotation.ControllerAdvice; 导入org.springframework.web.bind.annotation.ExceptionHandler;

    @ControllerAdvice 类GeneralExceptionHandler {

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

    }

  4. MyData.java

    包装示例;

    导入lombok.Data;

    @数据 公共类MyData {

    私有字符串名称;   私有字符串版本;

    }

  5. page.jsp

             $ {page.name}               $ {page.version123}   

2 个答案:

答案 0 :(得分:0)

您可以使用@ExceptionHandler注释来捕获特定的异常,为此,您可以简单地使用@ExceptionHandler在控制器内部注释一个方法,并为其提供特定的异常,例如:

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

这种方法的局限性在于,它将仅处理声明@RequestMapping的{​​{1}}引发的异常。为了避免这种限制,您可以使用控制器建议,它允许您使用完全相同的异常处理技术,但将其应用于整个应用程序,例如使用控制器建议:

@ExceptionHandler

提示:如果要捕获所有检查的异常,可以使用@ExceptionHandler(Exception.class)

答案 1 :(得分:0)

您可以对Controller中所有公共方法的切入点使用AOP。 我将BaseController用作所有Controller的基类。

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

然后添加AOP来处理Controller中从公共方法抛出的所有异常。

@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
    }
}