版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/uotail/article/details/86988545
目录描述
spring boot 中 默认的错误处理机制
在现在的前后端分离的项目中,我们的rest api 不仅会被浏览器访问,也会被非浏览器访问
404
对于一个错误的访问地址 http://127.0.0.1:8080/xxx
浏览器访问
非浏览器访问
总结
spring boot 错误处理 会对浏览器发出的请求返回html 页面
对 非浏览器发出的错误请求返回 json数据
404的message都为空
原理
核心类
org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
此类中只在类上面定义了一个映射路径,而在方法上没有定义具体的路径,所以这两个方法会处理同一个url,
不同之处是看请求头的accept 中是否带有 text/html ,如果带了就返回一个html页面,如果没有就返回json,
(同一个url不同情况做不同处理)
400
我们知道404 就是路径不存在 ,但有些情况下一个状态码不足以说明问题,如400
扫描二维码关注公众号,回复:
5419757 查看本文章
当有BindingResult errors 参数,验证不同过时则返回200
对于上面这个方法 如果没有 BindingResult errors 参数,当验证不同过时会直接被spring boot 档回去,返回400错误
用postman 请求这个方法http://127.0.0.1:8080/user
返回json数据
{
"timestamp": "2019-02-11T03:18:30.367+0000",
"status": 400,
"error": "Bad Request",
"errors": [
{
"codes": [
"MyConstraint.user.username",
"MyConstraint.username",
"MyConstraint.java.lang.String",
"MyConstraint"
],
"arguments": [
{
"codes": [
"user.username",
"username"
],
"arguments": null,
"defaultMessage": "username",
"code": "username"
}
],
"defaultMessage": "这是一个validate测试",
"objectName": "user",
"field": "username",
"rejectedValue": null,
"bindingFailure": false,
"code": "MyConstraint"
},
{
"codes": [
"NotBlank.user.password",
"NotBlank.password",
"NotBlank.java.lang.String",
"NotBlank"
],
"arguments": [
{
"codes": [
"user.password",
"password"
],
"arguments": null,
"defaultMessage": "password",
"code": "password"
}
],
"defaultMessage": "密码不能为空",
"objectName": "user",
"field": "password",
"rejectedValue": null,
"bindingFailure": false,
"code": "NotBlank"
}
],
"message": "Validation failed for object='user'. Error count: 2",
"path": "/user"
}
这下message也有值了
可见spring boot 对400的状态码会将错误信息收集到errors里面返回给用户
方法内部错误
对于400 404 我们的请求都没有进入方法里面就被spring boot 挡回去了
而更多的是方法内部错误的处理
对于这个方法
- 浏览器请求
这下返回500 服务内部错误,错误消息就是我自己写的那个 - 非浏览器访问
自定义浏览器错误
400
在resources下建立resources文件夹,再创建error文件夹,最后创建404 html错误页面
运行 测试如下
这个只对浏览器有作用,非浏览器请求返回错误信息不会变
500
和404同理
自定义非浏览器异常
自定义异常的默认处理
- 创建异常类
public class UserNotExistException extends RuntimeException{
private static final long serialVersionUID = -3807424756736653437L;
private String id;// 存放用户不存在的id
public UserNotExistException(String id){
super("user not exists ! ");
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
- 使用
/**
* @param idxx
* @return
*/
@GetMapping("{id:\\d++}")
@JsonView(User.UserSimpleView.class)
public User getInfo4( @PathVariable(name = "id") String idxx){
System.out.println("=================");
throw new UserNotExistException(idxx);
}
- 测试
自定义异常的自定义处理
spring boot 默认情况下不会读错误消息以外的信息
那我们如何拿到异常中的id呢
- 创建ControllerExceptionHandle
/**
* @version V1.0
* @Package com.whale.web
* @Description: 这个类只会处理其他controller抛出来的异常,不会处理请求
* @date 2019/2/11 12:12
*/
@ControllerAdvice
public class ControllerExceptionHandle{
@ExceptionHandler(UserNotExistException.class)
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Map<String,Object> handleUserNotExeistException(UserNotExistException ex){
Map<String,Object> result = new HashMap<>();
result.put("id",ex.getId());
result.put("messsage",ex.getMessage());
return result;
}
}
- 测试