springboot 访问html_Spring boot的异常处理

微信公众号:Java患者
专注Java领域技术分享

Spring boot的默认异常处理机制

我们以访问一个不存在的页面的场景为例,结果是返回一个错误页面:

8aa2bac434dde071e633a70f97418749.png

        而我们一个前后端分离的架构,我们写的Restful API往往会被多个渠道访问,比如浏览器,app。而我们的spring boo会根据不同的渠道做出不同的响应,是浏览器发的就返回html,不是则是json。若报错回跳转到/error的URL,同一个URL不同的处理方式是由Spring boot提供的BasicErrorController错误控制器实现的。

  // 如果请求头中accept有text/html这个值  @RequestMapping(produces = "text/html")  public ModelAndView errorHtml(HttpServletRequest request,      HttpServletResponse response) {    HttpStatus status = getStatus(request);    Map model = Collections.unmodifiableMap(getErrorAttributes(        request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));    response.setStatus(status.value());    ModelAndView modelAndView = resolveErrorView(request, response, status, model);    return (modelAndView == null ? new ModelAndView("error", model) : modelAndView);  }  // 没有则进到到这个方法里面  @RequestMapping  @ResponseBody  public ResponseEntity> error(HttpServletRequest request) {    Map body = getErrorAttributes(request,        isIncludeStackTrace(request, MediaType.ALL));    HttpStatus status = getStatus(request);    return new ResponseEntity>(body, status);  }

        当我们对请求的参数进行校验,当校验不通过时,spring boot会返回一个400状态码,并且并把我们所有的错误信息放进一个error里面来告诉我们客户端哪些字段有问题,问题是什么。

{    "timestamp": 1584868482621,    "status": 400,    "error": "Bad Request",    "exception": "org.springframework.web.bind.MethodArgumentNotValidException",    "errors": [        {            "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: 1",    "path": "/user/1"}

进入到服务里面抛出异常的处理机制

        一般如果是在我们的服务里面报的错误,Spring boot默认会响应给浏览器的是一个状态码的500的服务器错误。

06e7bcbe9954895d34924f86878fa54f.png

我们用postman模拟其他的渠道,返回的是:

{    "timestamp": 1584869332592,    "status": 500,    "error": "Internal Server Error",    "exception": "java.lang.RuntimeException",    "message": "user not exist",    "path": "/user/1"}

浏览器端自定义错误处理机制

        虽然由spring boot提供的默认处理机制可以很好的处理我们的异常。但有时候,我们也要去自定义异常处理来满足我们特定的需求场景。那么该如何自定义异常处理的呢?

        下面我们来实现404和500跳转到我们指定的页面,在我们的resources目录下创建我们相应的的html文件。注意文件目录和文件名要固定。

69b4fac373b716568036309d22206634.png

浏览器访问结果是跳转到我们特定的页面,

7d3039fdb04a03c9f6cc6ab4456de40f.png

        这种方式是安装spring boot的约束来自定义的,他仅能适用于浏览器的请求,而对app返回的任然是json。

其他的客户端自定义错误处理机制

        有些时候,我们的想要的异常返回结果还需要有其他的错误信息。下面我来实现用户不存在的异常。并且返回的异常包含不存在的用户得id。

public class UserNotExistException extends RuntimeException {  private static final long serialVersionUID = -6112780192479692859L;  private String id;  public UserNotExistException(String id) {    super("user not exist");    this.id = id;  }  public String getId() {    return id;  }  public void setId(String id) {    this.id = id;  }}

我们在服务里面抛出这个异常

  @GetMapping("{id:\\d+}")  @JsonView(User.UserDetailView.class)  public User getUserInfo(@PathVariable(name = "id") String id){        throw new UserNotExistException(id);  }

用我们postman访问:

{    "timestamp": 1584870909493,    "status": 500,    "error": "Internal Server Error",    "exception": "com.zhaohong.exception.UserNotExistException",    "message": "user not exist",    "path": "/user/1"}
        我们可以看到异常变了,是UserNotExistException,由于默认情况下,返回的异常不会去读message之外的信息,所以返回的结果中并没有包含用户的id,那么如何把这个id返回给前台。

下面我们自定义一个异常处理器。

@ControllerAdvicepublic class ControllerExceptionHandler {  @ExceptionHandler(UserNotExistException.class)  @ResponseBody  @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)  public Map handleUserNotExistException(UserNotExistException ex) {    Map result = new HashMap<>();    result.put("id", ex.getId());    result.put("message", ex.getMessage());    return result;  }}
        @ExceptionHandler指定了要捕获的异常,@ResponseStatus指定返回的状态码。

我们再次反问服务,结果是返回:

{    "id": "user not exist",    "message": "user not exist"}
查看 d0b6b10edc48fe61be1e5569121bb0fe.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值