作用
- 当程序出现异常时,跳转到指定异常页面,而不是服务器错误页面
- 当通过接口请求时,如果参数不对,可以抛出异常信息给前端
- 减少模版代码,使代码更简洁
接口校验类
自定义接口校验类,用于校验参数。
public class ApiAssert {
public static void isNull(Object object, String message) {
if (object != null) {
throw new ApiException(message);
}
}
public static void notNull(Object object, String message) {
if (object == null) {
throw new ApiException(message);
}
}
public static void isTrue(boolean expression, String message) {
if (!expression) {
throw new ApiException(message);
}
}
public static void notTrue(boolean expression, String message) {
if (expression) {
throw new ApiException(message);
}
}
public static void isEmpty(String txt, String message) {
if(!StringUtils.isEmpty(txt)) {
throw new ApiException(message);
}
}
public static void notEmpty(String txt, String message) {
if(StringUtils.isEmpty(txt)) {
throw new ApiException(message);
}
}
}
接口异常类
自定义接口异常类,如果参数不对,则抛出这个异常
public class ApiException extends RuntimeException {
private int code;
private String message;
public ApiException(String message) {
this.code = 201;
this.message = message;
}
public ApiException(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
全局异常处理类
自定义一个全局异常处理类,加上@ControllerAdvice
注解并加入容器中
@ControllerAdvice
@Component
public class GlobalExceptionHandler {
/**
* 错误页面统一处理
* @param request
* @param e
* @return
* @throws Exception
*/
@ExceptionHandler(value = Exception.class)
public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception {
e.printStackTrace();
ModelAndView mav = new ModelAndView();
mav.addObject("exception", e.getMessage());
mav.setViewName("error/error");
return mav;
}
/**
* 接口错误统一处理
* @param e
* @return
* @throws ApiException
*/
@ExceptionHandler(value = ApiException.class)
@ResponseBody
public Map<Integer,String> jsonErrorHandler(ApiException e) throws ApiException{
Map<Integer,String> map = new HashMap<>();
map.put(201, e.getMessage());
return map;
}
}
ControllerAdvice, 类注解, 作用于 整个 Spring 工程. ControllerAdvice 注解定义了一个全局的异常处理器
ExceptionHandler, 方法注解, 作用于 Controller 级别. ExceptionHandler 注解为一个 Controler 定义一个异常处理器
将GlobalExceptionHandler
类加入容器
<!-- 全局异常处理 -->
<context:component-scan base-package="cn.roothub.handler" />
异常页面
新建一个error
文件,里面在新建一个error.jsp
页面,用于跳转。
<div class="panel-body">
<h1>: (</h1>
<p>${exception}</p>
</div>
示例
普通请求
@RequestMapping(value = "/topic/{id}", method = RequestMethod.GET)
private String detail(@PathVariable Integer id, Model model,@RequestParam(value = "p", defaultValue = "1") Integer p,HttpServletRequest request) {
Topic topic = rootTopicService.findByTopicId(id);
if(topic == null) {
throw new RuntimeException("话题不存在");
}
用户发起查看话题的请求,参数是id
,后台通过id
查询数据库,得到一个Topic
对象。如果此时Topic
对象为空,则抛出RuntimeException
异常,并携带异常信息。Controller
层抛出异常后,会被我们自定义的全局异常处理类GlobalExceptionHandler
捕获,并进入defaultErrorHandler
方法,跳转到error
错误页面。
我们来访问一个不存在的话题试试
异常抛出了,跳转到我们指定的异常页面并携带了异常信息!
接口请求
@RequestMapping(value = "/topic/{id}", method = RequestMethod.GET)
@ResponseBody
private String detail(@PathVariable Integer id, Model model,@RequestParam(value = "p", defaultValue = "1") Integer p,HttpServletRequest request) {
Topic topic = rootTopicService.findByTopicId(id);
ApiAssert.notNull(topic, "话题消失了~");
继续访问一个不存在的话题试试
异常抛出了,并输出了异常信息!