以前抛异常常常是 这种样式:
如今我们可以这样:
如果正常,则:
========================================================
一般 前台向后台请求,一般是数据或页面请求,如果是数据请求(一般是json格式),我们除了将数据返回,还希望能告诉他这个请求是异常处理,还是正常处理。
===============================================================================================
1.创建一个返回对象,这样 即使抛出异常,也会返回json格式,如:
/**对于是 数据格式(json格式)请求时,返回类型是 JsonData
*
*/
@Getter
@Setter
public class JsonData {
private boolean ret; //判断请求是正常处理还是异常处理
private String msg; //返回的信息,可以为空
private Object data; //返回的数据
public JsonData(boolean ret){
this.ret=ret;
}
//返回数据和信息
public static JsonData success(Object object,String msg){
JsonData jsonData=new JsonData(true);
jsonData.data=object;
jsonData.msg=msg;
return jsonData;
}
//只返回数据
public static JsonData success(Object object){
JsonData jsonData=new JsonData(true);
jsonData.data=object;
return jsonData;
}
//什么都不返回
public static JsonData success(){
return new JsonData(true);
}
public static JsonData fail(String msg){
JsonData jsonData=new JsonData(false);
jsonData.msg=msg;
return jsonData;
}
public Map<String,Object> toMap(){
HashMap<String,Object> result=new HashMap<String, Object>();
result.put("ret",ret);
result.put("msg",msg);
result.put("data",data);
return result;
}
}
===============================================================================================
2.创建一个全局异常处理类:
@Slf4j
class SpringExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
//获得请求的地址
String url=httpServletRequest.getRequestURI().toString();
ModelAndView mv;
//如果请求是未知的,则用defaultMsg
String defaultMsg="System error";
// json 请求以 .json 结尾 ,page 请求以 .page 结尾
//instanceof 测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型
/**
* 之所以加toMap()方法,是因为在 ModelAndView中 允许传入一个map值,如: public ModelAndView(View view, Map<String, ?> model)
* 为了保证 正常返回结果 和 异常返回结果一致,所以 加了 toMap()方法
*/
/**
* 如果是已知的异常则用自己创建的,如果是未知的,则用defaultMsg
*
*/
if (url.endsWith(".json")){
//如果抛出的异常是 PermissionException 类型的,PermissionException 是自己创建的
if (e instanceof PermissionException){
JsonData result=JsonData.fail(e.getMessage());
mv=new ModelAndView("jsonView",result.toMap());
}else {
log.error("未知Json异常,url:"+url,e);
JsonData result=JsonData.fail(defaultMsg);
mv=new ModelAndView("jsonView",result.toMap());
}
}else if(url.endsWith(".page")) {
log.error("未知Page异常,url:"+url,e);
JsonData result=JsonData.fail(defaultMsg);
mv=new ModelAndView("exception",result.toMap());
}else{
log.error("未知异常,url:"+url,e);
JsonData result=JsonData.fail(defaultMsg);
mv=new ModelAndView("jsonView",result.toMap());
}
return mv;
}
}
===========================================================================================
public class PermissionException extends RuntimeException{
public PermissionException() {
super();
}
public PermissionException(String message) {
super(message);
}
public PermissionException(String message, Throwable cause) {
super(message, cause);
}
public PermissionException(Throwable cause) {
super(cause);
}
protected PermissionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
========================================================================================
@Controller
@RequestMapping("/test")
@Slf4j
public class TestController {
@RequestMapping("/hello.json")
@ResponseBody
public JsonData hello() {
log.info("hello++");
// throw new PermissionException("尝试异常");
return JsonData.success("hello,ddddddf permission");
}
}
==========================================================================================
疑点解答:1.为什摸要用 ModelAndView 作为 异常的返回类型呢?
因为:我们想要返回 json格式(也可以用其他的方式):
MappingJackson2JsonView
可自动渲染 JsonView
,当使用 MappingJackson2JsonView
配置应用,自动获取 jsonp
和 callback
参数使 json 数据自动转换成jsonp格式数据,支持跨域请求。