Restful Api 错误处理

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


在这里插入图片描述
在这里插入图片描述
当有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;
    }

}
  • 测试

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值