基于spring boot的统一异常处理

一、springboot 的默认异常处理

Spring Boot 提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并且该请求有一个全局的错误页面用来展示异常内容。

例如这里我们认为制造一个异常

    @GetMapping(value = "/boys")
    public List<Boy> boyList() throws Exception{
        throw new Exception("错误 ");
    }

使用浏览器访问 http://127.0.0.1:8080/boys

二、自定义的统一异常处理

虽然 Spring Boot 中实现了默认的 error 映射,但是在实际应用中,上面你的错误页面对用户来说并不够友好,我们通常需要去实现我们自己的异常提示。

1)统一的异常处理类 (com.dechy.handle)

@ControllerAdvice
public class ExceptionHandle {
private final static Logger logger </span>=<span style="color: rgba(0, 0, 0, 1)"> LoggerFactory.getLogger(ExceptionHandle.class);

<span style="background-color: rgba(255, 255, 0, 1)">@ExceptionHandler(value </span></span><span style="background-color: rgba(255, 255, 0, 1)">=</span><span style="color: rgba(0, 0, 0, 1)"><span style="background-color: rgba(255, 255, 0, 1)"> Exception.class)
@ResponseBody</span>
public Result handle(Exception e) {
    if (e instanceof BoyException) {
        BoyException boyException </span>=<span style="color: rgba(0, 0, 0, 1)"> (BoyException) e;
        return ResultUtil.error(boyException.getCode(), boyException.getMessage());
    }else {
        logger.error(</span><span style="color: rgba(128, 128, 128, 1)">"</span><span style="color: rgba(128, 128, 128, 1)">【系统异常】{}", e);</span>
        return ResultUtil.error(-<span style="color: rgba(128, 0, 128, 1)">1</span>, <span style="color: rgba(128, 128, 128, 1)">"</span><span style="color: rgba(128, 128, 128, 1)">未知错误");</span>

}
}
}

 2)自定义异常类 (com.dechy.exception)

public class BoyException extends RuntimeException{
private </span><span style="color: rgba(0, 0, 255, 1)">Integer</span><span style="color: rgba(0, 0, 0, 1)"> code;

public BoyException(ResultEnum resultEnum) {
    super(resultEnum.getMsg());
    this.code </span>=<span style="color: rgba(0, 0, 0, 1)"> resultEnum.getCode();
}

public </span><span style="color: rgba(0, 0, 255, 1)">Integer</span><span style="color: rgba(0, 0, 0, 1)"> getCode() {
    return code;
}

public void setCode(</span><span style="color: rgba(0, 0, 255, 1)">Integer</span><span style="color: rgba(0, 0, 0, 1)"> code) {
    this.code </span>=<span style="color: rgba(0, 0, 0, 1)"> code;
}

}

3)返回结果枚举 (com.dechy.enums)

public enum ResultEnum {
    UNKONW_ERROR(-1, "未知错误 "),
    SUCCESS(0, "成功 "),
    TOOSHORT(100, "身高太矮 "),
    TOOHIGH(101, " 身高太高"),

    ;
private </span><span style="color: rgba(0, 0, 255, 1)">Integer</span><span style="color: rgba(0, 0, 0, 1)"> code;

private </span><span style="color: rgba(0, 0, 255, 1)">String</span><span style="color: rgba(0, 0, 0, 1)"> msg;

ResultEnum(</span><span style="color: rgba(0, 0, 255, 1)">Integer</span> code, <span style="color: rgba(0, 0, 255, 1)">String</span><span style="color: rgba(0, 0, 0, 1)"> msg) {
    this.code </span>=<span style="color: rgba(0, 0, 0, 1)"> code;
    this.msg </span>=<span style="color: rgba(0, 0, 0, 1)"> msg;
}

public </span><span style="color: rgba(0, 0, 255, 1)">Integer</span><span style="color: rgba(0, 0, 0, 1)"> getCode() {
    return code;
}

public </span><span style="color: rgba(0, 0, 255, 1)">String</span><span style="color: rgba(0, 0, 0, 1)"> getMsg() {
    return msg;
}

}

4)返回结果工具类 (com.dechy.util)

public class ResultUtil {
public static Result success(</span><span style="color: rgba(0, 0, 255, 1)">Object</span> <span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)">) {
    Result result </span>=<span style="color: rgba(0, 0, 0, 1)"> new Result();
    result.setCode(</span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
    result.setMsg(</span><span style="color: rgba(128, 128, 128, 1)">"</span><span style="color: rgba(128, 128, 128, 1)">成功");</span>
    result.setData(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)">);
    return result;
}

public static Result success() {
    return success(null);
}

public static Result error(</span><span style="color: rgba(0, 0, 255, 1)">Integer</span> code, <span style="color: rgba(0, 0, 255, 1)">String</span><span style="color: rgba(0, 0, 0, 1)"> msg) {
    Result result </span>=<span style="color: rgba(0, 0, 0, 1)"> new Result();
    result.setCode(code);
    result.setMsg(msg);
    return result;
}

}

5)Boy 实体类 (com.dechy.model)


@Entity
public class Boy {
@Id
@GeneratedValue
private Integer id;
@NotBlank(message = "这个字段必传")
private String height;
@Min(value = 100, message = "体重必须大于 100")
private BigDecimal weight;
public Integer getId (){
return id;
}
public void setId (Integer id){
this.id = id;
}
public String getHeight (){
return height;
}
public void setHeight (String height){
this.height = height;
}
public BigDecimal getWeight (){
return weight;
}
public void setWeight (BigDecimal weight){
this.weight = weight;
}
@Override
public String toString (){
return "Boy{" + "id=" + id + ", height='"+ height +'\'' +", weight="+ weight +'}';
}
}
 

6)业务层具体使用时抛出异常,等待统一处理 (com.dechy.service)

    public void chooseBoy(Integer id) throws Exception{
        Boy boy= boyRepository.findOne(id);
        Integer height= boy.getHeight();
        if (height < 100) {
            // 返回"身高矮 " code=100
            throw new BoyException(ResultEnum.TOOSHORT);
        }else if (height > 200) {
            // 返回"身高太高 " code=101
            throw new BoyException(ResultEnum.TOOHIGH);
        }//...
    }