SpringBoot - 统一异常处理
前言
系统中往往有很多异常需要处理,到处处理异常也是大家经常做的事,为了便于管理,我们可以对异常进行统一的处理并统一的管理,就可以避免异常到处处理的情况,大大增加程序的可控性。
比如我们平时编写接口,遇到异常,不是直接打印异常的信息,而要统一格式,这才是合理的,我们就来讲讲。
统一返回格式
返回格式是指,无论与否有异常,返回的结果都是统一的,便于分辨和处理。
返回的格式
比如,错误返回值:
{
"code": 101,
"msg": "10到16岁",
"data": null
}
成功:
{
"code": 0,
"msg": "成功",
"data": {
"id": 2,
"name": "李四",
"age": 18
}
}
这样是不是就非常好判断数据的性质,是否异常,是哪里的异常,一目了然。
code,msg值是需要我们自己定义的,data的值,如果有异常那么就返回null,没异常就返回相应的数据。
统一结果
package cn.notemi.po;
/**
* Title:Result
* Description:http请求返回的最外层的对象
*
* @author Flicker
* @create 2017-08-05 下午 2:29
**/
public class Result<T> {
//错误码
private Integer code;
//提示信息
private String msg;
//具体的内容
private T data;
@Override
public String toString() {
return "Result{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
结果集合类
package cn.notemi.Util;
import cn.notemi.po.Result;
/**
* Title:ResultUtil
* Description:结果集合类
*
* @author Flicker
* @create 2017-08-05 下午 2:39
**/
public class ResultUtil {
//无异常
public static Result success(Object object){
Result result = new Result();
result.setCode(0);
result.setMsg("成功");
result.setData(object);
return result;
}
public static Result success(){
return success(null);
}
public static Result error(Integer code,String msg){
Result result = new Result();
result.setCode(code);
result.setMsg(msg);
return result;
}
}
使用枚举来定义管理异常
package cn.notemi.enums;
/**
* Title:ResultEnum
* Description:枚举统一管理异常信息
*
* @author Flicker
* @create 2017-08-05 下午 4:10
**/
public enum ResultEnum {
// UNKOWN_ERROR(-1,"未知错误"),
// SUCCESS(0,"成功"),
AGE_SMALL(100,"小于10岁"),
AGE_GENERALLY(101,"10到16岁")
;
private Integer code;
private String msg;
ResultEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
定义异常类
package cn.notemi.exception;
import cn.notemi.enums.ResultEnum;
/**
* Title:UserException
* Description:自定义异常类
*
* @author Flicker
* @create 2017-08-05 下午 3:56
**/
public class UserException extends RuntimeException{
private Integer code;
public UserException(ResultEnum resultEnum){
super(resultEnum.getMsg());
this.code = resultEnum.getCode();
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
异常捕获
package cn.notemi.handle;
import cn.notemi.Util.ResultUtil;
import cn.notemi.exception.UserException;
import cn.notemi.po.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* Title:ExceptionHandle
* Description:异常捕获类
*
* @author Flicker
* @create 2017-08-05 下午 3:49
**/
@ControllerAdvice
public class ExceptionHandle {
private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Result handle(Exception e){
//判断是否为自定义异常
if (e instanceof UserException){
UserException userException = (UserException)e;
return ResultUtil.error(userException.getCode(),userException.getMessage());
}else{
logger.error("系统异常",e);
return ResultUtil.error(-1,"未知错误");
}
}
}
Service
package cn.notemi.service;
import cn.notemi.Util.ResultUtil;
import cn.notemi.po.Result;
import cn.notemi.repository.UserRepository;
import cn.notemi.enums.ResultEnum;
import cn.notemi.exception.UserException;
import cn.notemi.po.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
/**
* Title:UserService
* Description:
*
* @author Flicker
* @create 2017-08-03 下午 6:24
**/
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public Result<User> getAge(Integer id)throws Exception{
User user = userRepository.findOne(id);
Integer age = user.getAge();
if (age<10){
//小于10岁
throw new UserException(ResultEnum.AGE_SMALL);
}else if(age>10&&age<16){
//10岁到16岁
throw new UserException(ResultEnum.AGE_GENERALLY);
}else{
return ResultUtil.success(user);
}
}
}
Controller
/**
* 查询某用户并判断年龄
* @param id
* @throws Exception
*/
@GetMapping(value = "/users/getage/{id}")
public Result<User> getAge(@PathVariable("id") Integer id)throws Exception{
return userService.getAge(id);
}