springboot 全局异常做法
利用自定义异常,可以让我们做一些自定义操作,比如实现一个不需要写 return ,就能在我们设定好的逻辑处发生错误,就自动 return 出去,从而不需要写 if 判断,再 return 的写法,从而让代码看起来更加简洁,下面简单举个列子:
利用自定义异常,判断请求参数非空,若是空,就自动 return 出去:
1、定义一个自定义异常类,继承想继承的异常,
package cn.wmadmin.co2.config; import cn.wmadmin.co2.util.Result; public class MyCustomException extends RuntimeException{ private ErrorEnum errorEnum; public MyCustomException(ErrorEnum errorEnum,String msg) { errorEnum.setCode(200); errorEnum.setMsg(msg); this.errorEnum=errorEnum; } public ErrorEnum getResponseStatusEnum() { return errorEnum; } public void setResponseStatusEnum(ErrorEnum responseStatusEnum) { this.errorEnum = responseStatusEnum; } }
2, 配置异常,添加自定义异常
package cn.wmadmin.co2.config; import cn.wmadmin.co2.util.Result; import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice @Slf4j public class GraceExceptionHandler { /** * 全局异常捕获 * @param e * @return */ @ExceptionHandler(Exception.class) @ResponseBody public Object returnException(Exception e) { log.error("error",e); System.out.println("异常为:666"); return Result.build(500,"全局异常啦啦啦"+e.getMessage()); } /** * 自定义异常 * @param e * @return */ @ExceptionHandler(value = MyCustomException.class) @ResponseBody public Object returnMyCustomException(MyCustomException e) { log.info("异常为:"+e.getResponseStatusEnum()); System.out.println("异常为:777"+ErrorEnum.PARAM_IS_NOT_NULL.getMsg()); return Result.exception(e.getResponseStatusEnum()); } }
重点是:这个配置类上的注解:@RestControllerAdvice ,方法上的注解 @ExceptionHandler(Exception.class)
之后程序里面,一旦发生了任何异常,都会走这里的异常方法,即可达到全局异常捕获!
==============
3, Result 统一返回格式工具类
package cn.wmadmin.co2.util; import cn.wmadmin.co2.config.ErrorEnum; import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; /** * 接口返回数据格式 * @author scott * @date 2019年1月19日 */ @Data @ApiModel(value="接口返回对象", description="接口返回对象") public class Resultimplements Serializable { private static final long serialVersionUID = 1L; /** * 成功标志 */ @ApiModelProperty(value = "成功标志") private boolean success = true; /** * 返回处理消息 */ @ApiModelProperty(value = "返回处理消息") private String message = ""; /** * 返回代码 */ @ApiModelProperty(value = "返回代码") private Integer code = 0; /** * 返回数据对象 data */ @ApiModelProperty(value = "返回数据对象") private T result; /** * 时间戳 */ @ApiModelProperty(value = "时间戳") private long timestamp = System.currentTimeMillis(); public Result() { } /** * @param code * @param message */ public Result(Integer code,String message) { this.code = code; this.message = message; } public Result<T> success(String message) { this.message = message; this.code = 200; this.success = true; return this; } public static<T> Result<T> OK() { Result<T> r = new Result (); r.setSuccess(true); r.setCode(200); return r; } public static<T> Result<T> OK(String msg) { Result<T> r = new Result<T>(); r.setSuccess(true); r.setCode(200); r.setMessage(msg); //Result OK(String msg)方法会造成兼容性问题 issues/I4IP3D r.setResult((T) msg); return r; } public static<T> Result<T> OK(T data) { Result<T> r = new Result<T>(); r.setSuccess(true); r.setCode(200); r.setResult(data); return r; } public static<T> Result<T> OK(String msg, T data) { Result<T> r = new Result<T>(); r.setSuccess(true); r.setCode(200); r.setMessage(msg); r.setResult(data); return r; } public static<T> Result<T> error(String msg, T data) { Result<T> r = new Result<T>(); r.setSuccess(false); r.setCode(500); r.setMessage(msg); r.setResult(data); return r; } public static Result<Object> error(String msg) { return error(500, msg); } public static Result<Object> error(int code, String msg) { Result
4,自定义枚举类
package cn.wmadmin.co2.config; /** * 自定义异常枚举类 */ public enum ErrorEnum { //自定义系列 USER_NAME_IS_NOT_NULL(10001,"【参数校验】用户名不能为空"), PWD_IS_NOT_NULL(10002,"【参数校验】密码不能为空"), PARAM_IS_NOT_NULL(10003,"【参数校验】不能为空"), //400系列 BAD_REQUEST(400,"请求的数据格式不符!"), UNAUTHORIZED(401,"登录凭证过期!"), FORBIDDEN(403,"抱歉,你无权限访问!"), NOT_FOUND(404, "请求的资源找不到!"), //500系列 INTERNAL_SERVER_ERROR(500, "服务器内部错误!"), SERVICE_UNAVAILABLE(503,"服务器正忙,请稍后再试!"), //未知异常 UNKNOWN(10000,"未知异常!"); /** 错误码 */ private Integer code; /** 错误描述 */ private String msg; ErrorEnum(Integer code, String msg) { this.code = code; this.msg = msg; } public Integer setCode(Integer code) { this.code = code; return this.code; } public Integer getCode() { return code; } public String setMsg(String msg) { this.msg = msg; return this.msg; } public String getMsg() { return msg; } }
5,用法
if(this.adminId==0){ throw new MyCustomException(ErrorEnum.PARAM_IS_NOT_NULL,"错误,adminId为空"); }