我使用此演示构建了自己的Spring boot 2.x应用程序:https://spring.io/guides/gs/spring-boot/我遇到的问题是,当Spring / Spring boot中出现异常时,它会打印到标准输出中。我不要我想捕获它们并进行其他处理,例如记录它们。我可以捕获代码异常,但不能捕获Spring / Spring引导异常。因此,如何捕获Spring / Spring Boot 2.x的所有异常,以便能够处理它们?有没有像通用异常捕获器这样的简单方法?有人可以告诉我一些代码吗?
我的代码:
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);
}
}
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;
}
}
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");
}
}
MyData.java
包装示例;
导入lombok.Data;
@数据 公共类MyData {
私有字符串名称; 私有字符串版本;
}
page.jsp
$ {page.name} $ {page.version123}
答案 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
}
}