17、springboot——定制错误响应(2)
二、如何定制错误响应
1).如何定义错误处理页面
1.1、有模板引擎的情况下;error/状态码;
【将错误页面命名为 (错误状态码.html) 放在模板引擎文件夹里面的error文件夹下】
发生此状态码的错误就会来到 对应的页面;
可以使用4xx、5xx作为错误页面的文件名来匹配这种类型的所有错误
精确优先(优先寻找精确的状态码.html);
页面能获取的信息( DefaultErrorAttributes)
timestamp:时间戳
status:状态码
error:错误提示
exception:异常对象
message:异常消息
errors:JSR303数据校验的错误都在这里
这时出现400错误码时:
1.2、没有模板引擎(模板引擎找不到这个错误页面),静态资源文件下找
1.3、默认以上两中都没有的时候,默认来到springboot的默认页面
2)、定制json数据
自定义UserNotExistException异常
public class UserNotExistException extends RuntimeException { public UserNotExistException() { super("the user is not existen!"); } }
设置什么情况下出现这个异常
@ResponseBody @RequestMapping("/hello") public String hello(@RequestParam("user")String user){ //当传入的参数user为aaa时就抛出自定义的UserNotExistException if(user.equals("aaa")){ throw new UserNotExistException(); } return "hello world"; }
异常页面:
<h1>status:[[${status}]]</h1> <h1>timestamp:[[${timestamp}]]</h1> <h1>error:[[${error}]]</h1> <h1>message:[[${message}]]</h1>
此时访问符合出现异常的链接
页面显示了我们自定义异常返回的信息
其他客户端的访问:
3)、自定义异常处理返回json数据
方式一:没有自适应效果(即浏览器和其它客户端返回的都是json)
@ControllerAdvice public class MyExceptionHandler { //1、浏览器和其它客户端返回的都是json @ResponseBody @ExceptionHandler(UserNotExistException.class) public Map<String,Object> handleException(Exception e){ Map<String,Object> map = new HashMap<>();
//设置定义信息 map.put("code","user.not.exist"); map.put("message",e.getMessage()); return map; } }
浏览器访问出现此异常链接时:
其它客户端访问此异常链接时:
方式二:*********转发到/error进行自适应响应效果处理(即web浏览器响应html,其它客户端返回json)*********
修改自定义的异常处理器
@ControllerAdvice public class MyExceptionHandler { //通过转发到error进行自适应响应效果处理(即web响应页面;其它客户端响应json) @ExceptionHandler(UserNotExistException.class) public String handleException(Exception e, HttpServletRequest request){ Map<String,Object> map = new HashMap<>(); //传入我们自己的错误状态码,不传默认就是200 request.setAttribute("javax.servlet.error.status_code","500"); //这里设置的状态码是500所以我们返回的错误页面是5xx.html;有500.html则返回500.html
//放入自定义的信息 map.put("ccode","user.not.exist"); map.put("message",e.getMessage()); //这里获取的是异常类UserNotExistException中的信息
//将数据放到request域中
request.setAttribute("ext",map);
//通过转发到error使能够进行自适应响应效果处理
return "forward:/error";
}
}
5xx.html中的代码回显;
<h1>status:[[${status}]]</h1> <h1>timestamp:[[${timestamp}]]</h1> <!--自定义的信息回显--> <h1>extMessage1:[[${ext.m1}]]</h1> <h1>extMessage2:[[${ext.m2}]]</h1>
WEB浏览器测试(返回的是html页面):
而其它客户端返回的是json数据(这里就不截图了,自行测试)
4)在容器中添加全局的返回信息(比如公司名称 等等。。。)
自定义ErrorAttributes类
//给容器中加入我们自定义的ErrorAttributes @Component public class MyErrorAttributes extends DefaultErrorAttributes { @Override public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) { Map<String, Object> map = super.getErrorAttributes(webRequest, includeStackTrace);
//加入自己定义信息 map.put("company","阿里");
//加入从异常处理器放入request域中信息 Map<String,Object> ext = (Map<String, Object>) webRequest.getAttribute("ext", 0); map.put("ext",ext); //返回总的自定义信息 return map; } }
修改5xx.html
<h1>status:[[${status}]]</h1> <h1>timestamp:[[${timestamp}]]</h1> <!--自定义的信息回显--> <h1>extMessage1:[[${ext.m1}]]</h1> <h1>extMessage2:[[${ext.m2}]]</h1> <!--自己在容器中添加的全局返回信息--> <h1>company:[[${company}]]</h1>
WEB浏览器访问:
其它客户端访问返回的json字符串中也有company属性,说明全局返回信息配置成功