Spring 统一异常处理有 3 种方式,分别为:
1.使用 @ ExceptionHandler 注解
2.实现 HandlerExceptionResolver 接口
3.使用 @controlleradvice 注解
我们知道,系统中异常包括:编译时异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。在开发中,不管是dao层、service层还是controller层,都有可能抛出异常,在springmvc中,能将所有类型的异常处理从各处理过程解耦出来,既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护。
处理思路
系统的dao、service、controller出现异常都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理。springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。
处理逻辑:
捕获整个系统中发生的异常。
1、异常写入日志文件
2、及时通知开发人员。发邮件、短信。
3、展示一个错误页面,例如:您的网络故障,请重试。
现在开始编写全局异常处理类
GlobalExceptionHandler
package com.guli.teacher.exception;
import com.guli.common.result.ExceptionUtil;
import com.guli.common.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 全局异常处理器
*/
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
//1、全局异常类型 Exception
@ExceptionHandler(Exception.class)
@ResponseBody
public Result error(Exception e){
e.printStackTrace();
return Result.error().message("出错了");
}
@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public Result ArithmeticExceptionError(Exception e){
e.printStackTrace();
return Result.error().message("除数不能为0");
}
@ExceptionHandler(EduException.class)
@ResponseBody
public Result error(EduException e){
e.printStackTrace();
//log.error(e.getMessage());
// 输出到硬盘日志下
log.error(ExceptionUtil.getMessage(e));
return Result.error().code(e.getCode()).message(e.getMsg());
}
}
EduException
package com.guli.teacher.exception;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "全局异常")
public class EduException extends RuntimeException {
@ApiModelProperty(value = "状态码")
private Integer code;
@ApiModelProperty(value = "异常消息")
private String msg;
@Override
public String toString() {
return "EduException{" +
"message=" + this.getMsg() +
", code=" + code +
'}';
}
}
ExceptionUtil
package com.guli.common.result;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
public class ExceptionUtil {
public static String getMessage(Exception e) {
StringWriter sw = null;
PrintWriter pw = null;
try {
sw = new StringWriter();
pw = new PrintWriter(sw);
// 将出错的栈信息输出到printWriter中
e.printStackTrace(pw);
pw.flush();
sw.flush();
} finally {
if (sw != null) {
try {
sw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (pw != null) {
pw.close();
}
}
return sw.toString();
}
}
EduTeacherController
@ApiOperation(value = "根据ID查询")
@GetMapping("{id}")
public Result selectTeacherById(
@ApiParam(name="id",value = "讲师ID", required = true)
@PathVariable String id){
/* 当我们的业务被非法参数操作时、我们可以自定义异常(业务异常)*/
EduTeacher teacher = teacherService.getById(id);
if(teacher == null){
throw new EduException(ResultCode.EDU_ID_ERROR,"没有此讲师信息");
}
try {
// EduTeacher teacher = teacherService.getById(id);
return Result.ok().data("teacher",teacher);
} catch (Exception e) {
e.printStackTrace();
return Result.error();
}
}