在Springboot或者Springcloud开发中为了统一处理业务异常,需要自定义全局异常处理类统一处理业务异常。在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping注解的方法中,本篇内容笔者讲解一下使用@ControllerAdvice和@ExceptionHandler注解,自定义全局异常处理类,统一处理异常。
一、@ExceptionHandler注解介绍
启动应用后,@ExceptionHandler注解都会作用在被@RequestMapping注解的方法上。
@ExceptionHandler 拦截了异常,我们可以通过该注解的value实现自定义异常拦截处理。其中,@ExceptionHandler 配置的 value 指定需要拦截的异常类型。
二、自定义业务异常类和全局异常处理类
1、编写自定义业务异常类:
-
package com.demo.serverProvider.entity; -
/** -
* 创建时间:2019年3月2日 上午11:22:09 -
* 项目名称:server-provider -
* 类说明:自定义业务异常类 -
* @author guobinhui -
* @since JDK 1.8.0_51 -
*/ -
public class BizException extends RuntimeException{ -
private static final long serialVersionUID = 2870428181462432015L; -
private String code; -
private String msg; -
public BizException(String code, String msg) { -
this.code = code; -
this.msg = msg; -
} -
public String getCode() { -
return code; -
} -
public void setCode(String code) { -
this.code = code; -
} -
public String getMsg() { -
return msg; -
} -
public void setMsg(String msg) { -
this.msg = msg; -
} -
}
注:spring 对于 RuntimeException 异常才会进行事务回滚。
2、编写全局异常处理类
-
package com.demo.serverProvider.handler; -
import java.util.HashMap; -
import java.util.Map; -
import org.springframework.web.bind.annotation.ControllerAdvice; -
import org.springframework.web.bind.annotation.ExceptionHandler; -
import org.springframework.web.bind.annotation.ResponseBody; -
import com.demo.serverProvider.entity.BizException; -
/** -
* 创建时间:2019年3月2日 上午11:27:02 -
* 项目名称:server-provider -
* 类说明:自定义全局异常处理类 -
* @author guobinhui -
* @since JDK 1.8.0_51 -
*/ -
@ControllerAdvice -
public class GlobalExceptionHandler { -
/** -
* 全局异常捕捉处理 -
* @param ex -
* @return -
*/ -
@ResponseBody -
@ExceptionHandler(value = Exception.class) -
public Map<String,Object> defaultExceptionHandler(Exception ex) { -
Map <String,Object> map = new HashMap <String,Object> (); -
map.put("code", 500); -
map.put("msg", ex.getMessage()); -
return map; -
} -
/** -
* 拦截捕捉自定义业务异常 BizException.class -
* @param ex -
* @return -
*/ -
@ResponseBody -
@ExceptionHandler(value = BizException.class) -
public Map<String,Object> defaultExceptionHandler(BizException ex) { -
Map<String,Object> map = new HashMap<String,Object>(); -
map.put("code", ex.getCode()); -
map.put("msg", ex.getMsg()); -
return map; -
} -
}
3、controller中抛出异常进行测试
-
package com.demo.serverProvider.controller; -
import java.util.ArrayList; -
import java.util.Iterator; -
import java.util.List; -
import org.springframework.web.bind.annotation.RequestMapping; -
import org.springframework.web.bind.annotation.RestController; -
import com.demo.serverProvider.entity.BizException; -
/** -
* 创建时间:2019年3月1日 下午4:03:44 -
* 项目名称:server-provider -
* 类说明: -
* @author guobinhui -
* @since JDK 1.8.0_51 -
*/ -
@RestController -
@RequestMapping(value="/fileHandler") -
public class ReadFilesController { -
@RequestMapping("/test") -
public String test() throws BizException{ -
StringBuffer message = new StringBuffer(); -
message.append("出现异常:【"); -
throw new BizException("400", message.toString() +"数据错误】"); -
} -
}
启动应用,访问:http://localhost:8891/fileHandler/test,正常显示以下json内容,证明业务异常已经被自定义异常处理类成功拦截
-
<Map> -
<msg>出现异常:【数据错误】</msg> -
<code>400</code> -
</Map>
如果不需要返回json数据,而要渲染某个页面模板返回给浏览器,那么异常处理类GlobalExceptionHandler中可以这么实现:
-
@ExceptionHandler(value = BizException.class) -
public ModelAndView defaultExceptionHandler(BizException ex) { -
ModelAndView modelAndView = new ModelAndView(); -
modelAndView.setViewName("error"); -
modelAndView.addObject("code", ex.getCode()); -
modelAndView.addObject("msg", ex.getMsg()); -
return modelAndView; -
}
在 templates 目录下,添加 error.ftl(这里使用freemarker) 进行渲染:
-
<!DOCTYPE html> -
<html lang="en"> -
<head> -
<meta charset="UTF-8"> -
<title>异常页面</title> -
</head> -
<body> -
<h1>${code}</h1> -
<h1>${msg}</h1> -
</body> -
</html>
重启应用,http://localhost:8891/fileHandler/test 显示自定义的异常页面内容。
在Springboot或Springcloud开发中,为统一处理业务异常,可使用@ControllerAdvice和@ExceptionHandler注解自定义全局异常处理类。本文介绍了@ExceptionHandler注解,还讲解了编写自定义业务异常类、全局异常处理类,并在controller中测试,同时提及渲染页面模板处理异常的方法。
4738

被折叠的 条评论
为什么被折叠?



