目录

前言

系统中往往有很多异常需要处理,到处处理异常也是大家经常做的事,为了便于管理,我们可以对异常进行统一的处理并统一的管理,就可以避免异常到处处理的情况,大大增加程序的可控性。

比如我们平时编写接口,遇到异常,不是直接打印异常的信息,而要统一格式,这才是合理的,我们就来讲讲。

统一返回格式

返回格式是指,无论与否有异常,返回的结果都是统一的,便于分辨和处理。

返回的格式

比如,错误返回值:

{
    "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);
    }