java - 如何捕获 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>
解决方案
您可以使用@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)
推荐阅读
- r - 当有多个部分需要对数据进行规范化时,如何找到大型数据集的中值规范化
- django - 使用 Vue JS 和 Django 进行身份验证?
- java - 抽象方法中的多态性和检查异常抛出
- google-cloud-platform - Terraform 远程后端未填充
- arrays - 对数组和散列的红宝石散列进行排序
- javascript - 解析异步读取的 json 文件时 JSON 输入意外结束
- sql-server - 执行过程中转换数据类型时出错
- css - 如果单元格更宽,是否可以在不单击文本的情况下启动下拉菜单列表项?
- javascript - Angular 属性指令和有效的可访问 HTML
- git - 尝试压缩提交后,交互式变基不断添加步骤