作者:一一哥
经过上一章节的学习,我们了解了Spring Boot底层是怎么处理error的。那么看了上面的源码后,我们是否可以自己定义404或者500的错误页面返回给客户端呢?
Spring Boot开发指南上提供了以下四种方式:
1️⃣. 自定义一个bean,实现ErrorController接口,那么默认的错误处理机制将不再生效;
2️⃣. 自定义一个bean,继承BasicErrorController类,使用一部分现成的功能,自己也可以添加新的public方法,使用@RequestMapping及其produces属性指定新的地址映射;
3️⃣. 自定义一个ErrorAttribute类型的bean,那么还是默认的两种响应方式,只不过改变了内容项而已;
4️⃣. 继承AbstractErrorController.
接下来我给大家简单讲解几种实现自定义错误的处理实现方式。
首先我们讲解一个简单的实现错误处理的方式,就是用我们自定义的html页面来替换默认的”whitelabel“页面。
目录结构如下,创建过程略。
我们在src/main/resources路径下,新建文件夹reources/static/error文件夹,然后新建404.html和500.html,然后编写自己想要的错误内容即可:
404
亲,你要找的页面跑到火星去了哦...
500
服务器有点累了...
我们创建一个Controller类,里面创建两个测试接口方法。
package com.yyg.boot.web;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @Description Description
* @Author 一一哥Sun
* @Date Created in 2020/3/27
*/
@Controller
public class HelloController {
@ResponseBody
@GetMapping("/show")
public String showMsg() {
return "success";
}
@GetMapping("/showError")
public void showError() {
throw new RuntimeException("自定义异常...");
}
}
正常访问时的效果:
产生404异常时跳转到的页面:
产生500错误时跳转到的页面:
上面的实现方式虽然简单,但是这种自定义错误页面的方式只对浏览器有效,对非浏览器发送来的请求则不会生效,效果如下:
因此下面我们讲一下如何通过自定义异常处理来解决这个问题。
接下来我们通过@ControllerAdvice
和@ExceptionHandler
注解,来统一定义处理不同的Exception,从而映射到不同的错误处理页面.
而当我们要实现RESTful API时,返回的错误是JSON格式的数据,而不是HTML页面,这时我们只需在@ExceptionHandler
之后加入@ResponseBody
,就能将处理函数return的内容转换为JSON格式.
下面具体讲述如何实现返回JSON格式的异常处理方案.
我们继续在上一个案例的项目中完成下面的内容。
创建统一的JSON返回对象,code:消息类型;message:消息内容;url:请求的url;data:请求返回的数据.
package com.yyg.boot.domain;
import lombok.Data;
/**
* @Description Description
* @Author 一一哥Sun
* @Date Created in 2020/3/27
*/
@Data
public class ErrorInfo {
public static final Integer OK = 0;
public static final Integer ERROR = 100;
private Integer code;
private String message;
private String url;
private T data;
}
该类用来实验捕获该异常,并返回json.
package com.yyg.boot.exception;
/**
* @Description 自定义异常类
* @Author 一一哥Sun
* @Date Created in 2020/3/27
*/
public class CustomException extends Exception{
public CustomException(String message) {
super(message);
}
}
@RequestMapping("/json")
public String handleJsonException() throws CustomException {
throw new CustomException("json格式的异常处理方案...");
}
在com.yyg.boot.exception中创建一个全局的GlobalExceptionHandler异常处理类,在该类上添加@ControllerAdvice注解。
package com.yyg.boot.exception;
import com.yyg.boot.domain.ErrorInfo;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
/**
* @Description Description
* @Author 一一哥Sun
* @Date Created in 2020/3/27
*/
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = CustomException.class)
@ResponseBody
public ErrorInfo jsonErrorHandler(HttpServletRequest req, CustomException e) throws Exception {
ErrorInfo info = new ErrorInfo<>();
info.setMessage(e.getMessage());
info.setCode(ErrorInfo.ERROR);
info.setData("JSON格式异常处理信息");
info.setUrl(req.getRequestURL().toString());
return info;
}
}
启动应用,访问:http://localhost:8080/json,得到如下响应内容:
此时会发现无论是用浏览器,还是postman,测试得到的结果都是jsno格式的数据。
至此,已完成在Spring Boot中创建统一的异常处理,实际实现还是依靠Spring MVC的注解,更多更深入的使用可参考Spring MVC的文档.