一、定制错误页面
1、有模板引擎的情况下;error/状态码; 【将错误页面命名为 错误状态码.html 放在模板引擎文件夹里面的 error文件夹下】,发生此状态码的错误就会来到 对应的页面;
我们可以使用4xx和5xx作为错误页面的文件名来匹配这种类型的所有错误,精确优先(优先寻找精确的状态 码.html);
页面能获取的信息;
timestamp:时间戳
status:状态码
error:错误提示
exception:异常对象
message:异常消息
errors:JSR303数据校验的错误都在这里
2、没有模板引擎(模板引擎找不到这个错误页面),静态资源文件夹下找;
所以把error页面放到static文件夹下也ok,但是无法使用模板引擎解析数据
3、以上都没有错误页面,就是默认来到SpringBoot默认的错误提示页面;
二、定制错误的json数据
1、自定义异常处理&返回定制json数据
@RequestMapping("/hi")
@ResponseBody
public String hi(@RequestParam("user") String user)
{
if (user.equals("aaa")){
throw new UserNotExistException();
}
return "hello";
}
public class UserNotExistException extends RuntimeException{
public UserNotExistException() {
super("用户不存在");
}
}
浏览器访问:http://localhost:8081/crud/hi?user=111 (正常)
浏览器访问:http://localhost:8081/crud/hi?user=aaa
说明:页面中使用模板引擎解析数据
postman客户端访问:http://localhost:8081/crud/hi?user=aaa
返回定制json数据
@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(UserNotExistException.class)
@ResponseBody
public Map<String,Object> handlerException(Exception e){
Map<String,Object> map = new HashMap<>();
map.put("code","user not exit");
map.put("message",e.getMessage());
return map;
}
}
浏览器访问:http://localhost:8081/crud/hi?user=aaa
postman客户端访问:http://localhost:8081/crud/hi?user=aaa
这种做法有一个缺点,就是浏览器和客户端返回的都是json数据,那么如何做到自适应呢?
方式一总结:实现了自定义错误页面和json数据,但是浏览器和客户端没有实现自适应
2、转发到/error进行自适应响应效果处理
@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(UserNotExistException.class)
public String handlerException(Exception e){
Map<String,Object> map = new HashMap<>();
map.put("code","user not exit");
map.put("message",e.getMessage());
//转发到/error进行自适应响应效果处理
return "forward:/error";
}
}
浏览器访问:http://localhost:8081/crud/hi?user=aaa
postman客户端访问:http://localhost:8081/crud/hi?user=aaa
但是这样做又成了默认了空白页面,而不是我们自定义的错误页面。注意到这里的错误状态码是200,而不是4XX,5XX
修改上述代码为:传入我们自己的错误状态码 4xx 5xx,否则就不会进入定制错误页面的解析流程
@ExceptionHandler(UserNotExistException.class)
public String handlerException(Exception e, HttpServletRequest request){
Map<String,Object> map = new HashMap<>();
request.setAttribute("javax.servlet.error.status_code",500);
map.put("code","user not exit");
map.put("message",e.getMessage());
//转发到/error进行自适应响应效果处理
return "forward:/error";
}
浏览器访问:http://localhost:8081/crud/hi?user=aaa
postman客户端访问:http://localhost:8081/crud/hi?user=aaa
这样做实现了自适应效果!!!!
方式二总结:实现了自定义错误页面,浏览器和额客户端实现了自适应,但是没有实现定制的json数据格式
3、将定制数据携带出去
出现错误以后,会来到/error请求,会被BasicErrorController处理,响应出去可以获取的数据是由 getErrorAttributes得到的(是AbstractErrorController(ErrorController)规定的方法);
(1)完全来编写一个ErrorController的实现类【或者是编写AbstractErrorController的子类】,放在容器中;
(2)页面上能用的数据,或者是json返回能用的数据都是通过errorAttributes.getErrorAttributes得到;
容器中DefaultErrorAttributes.getErrorAttributes();默认进行数据处理的;
自定义ErrorAttributes
@Component
public class MyErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
Map<String, Object> map = super.getErrorAttributes(requestAttributes, includeStackTrace);
map.put("myerror","小新新自定义的错误呀");
return map;
}
}
浏览器访问:
postman客户端访问:
方式三总结:实现了自定义错误页面和定制的json数据格式,浏览器和额客户端实现了自适应
三、总结和代码整理
1、希望达到的效果:浏览器实现自定义页面相应,客户端相应自定义的json数据格式,浏览器和客户端自适应
(1)Controller
(2)异常类 UserNotExistException
(3)异常处理器
这里需要写状态码!!!!
(4)定制错误属性
2、最终的效果:响应是自适应的,可以通过定制ErrorAttributes改变需要返回的内容,
浏览器访问:http://localhost:8081/crud/hi?user=aaa
postman客户端访问:http://localhost:8081/crud/hi?user=aaa
------------------------------------------------------------------------------------------------------------------------
补充说明:使用了springboot默认的错误处理机制,文件存放位置及格式如下:
EG:5XX.html