通常咱们后台出错报Exception都是直接抛出来的,可是微信公众号,或者支付宝支付等等,他们的异常都有错误码对应错误信息,他们是如何根据错误信息展现对应的错误码提供给前端的呢,这也就是咱们要说的统一错误消息处理机制。前端
首先建立一个Result类,这个类做用是设置消息码以及消息文本还有消息数据,以下所示数据库
package com.xfind.util.result; public class Result<T> { private int code; private String message; private T data; public Result(){ } public Result(int code, String message, T data) { this(code, message); this.data = data; } public Result(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Object getData() { return data; } public void setData(T data) { this.data = data; } }
设置以后 ,咱们接下来再建立一个ResultCode类,这个类的做用是具体的消息码和消息,以下所示:微信
package com.xfind.util.result; /** * 异常处理状态码 */ public enum ResultCode { SUCCESS(0, "请求成功"), Unknown_Exception(-1, "未知异常"), USER_NOT_FOUND(10001, "没有找到此用户"), USERNAME_NOT_BLANK(10002, "用户名不能为空"), USERNAME_EXIST(10003, "用户名已经存在"), USERTYPE_ERROR(100031, "用户类型不正确"), PHONE_WROND(10004, "手机号不正确"), SMS_CODE_ERROR(10007, "手机验证码不正确"), PHONE_EXIST(10008, "手机号已经存在"), USER_EMPTY_EXCEPTION(10009, "用户名、手机号或者邮箱为空"), USER_TOKEN_EXCEPTION(10010, "从TOKEN中未查到相关用户信息"), USERNAME_PASSWORD_EXCEPTION(10011, "用户名或者密码错误"), EMAIL_SERVER_ECCEPTION(10012, "阿里云邮件服务端出错"), EMAIL_CLIENT_ECCEPTION(10013, "阿里云邮件客户端出错"), EMAIL_SEND_ECCEPTION(10014, "阿里云邮件发送出错"), EMAIL_WROND(10015, "邮箱不正确"), EMAIL_CODE_WROND(10016, "邮箱验证码不正确"), EMAIL_EXIST(10017, "邮箱已经存在"), LOGIN_METHOD_WROND(10018, "登陆方式不正确"), CODE_EMPTY(10019, "验证码不为空"), PASSWORD_EMPTY(10020, "密码不为空"), TOKEN_EXCEPTION(10021, "TOKEN认证出错"), USER_AUTH_FAILD(10022, "用户认证失败"), USER_ACCESS_DENIED(10023, "用户无权限登陆"), CODE_SEND_FAILD(10030, "验证码发送失败"), ACTION_MONGODB_ERROR(10100, "操做MONGODB数据库出错"), OPERATION_TOO_FREQUENT(10101, "请求过于频繁,请稍候再试"), GOLD_COINS_INSUFFICIENT(10025,"金币余额不足"), CODE_EXIST(10023,"编号已存在"), TESTCODE_EXIST(10033,"答题码已存在"), TESTCODE_NOEXIST(10034,"答题码不存在"), TESTCODE_ERROR(10036,"提交数已达上限"), TESTCENTER_NOEXIST(10035,"测试题不存在"), NAME_EXIST(10024,"名称已存在"), NOT_EXIST_EMAIL(10025,"该企业用户没有分配邮箱"), MAIL_REACH_MAX(10026,"达到收取邮箱上限"), MAIL_NEW_NOTEXIST(10027,"邮箱中没有可导入的简历"), PWD_CONFIRM_ERROR(10029,"两次密码不一致"), PWD_ERROR(10030,"密码不正确"), ENTER_OR_TALENT_NOT_EXITS(10028,"企业或人才库简历不存在"), PHONE_EMPTY(10031, "手机号不能为空"), EMAIL_EMPTY(10032, "邮箱不能为空"), NO_USABLE_MAIL(10040,"没有可用邮箱"), REQUESTRECORD_EXIST(10050,"简历已投递"), TALENTRESERVER_EXIST(10051,"简历已存在于人才储备库中,请勿重复添加"), DEVICE_ID_EMPTY(10052,"设备ID:deviceId不能为空"), DELETE_CONNECT_ERROR(10053,"删除connect出错"); private int code; private String message; ResultCode(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public String getMessage() { return message; } }
好了,有了Result和ResultCode类,咱们就能够来编写异常并返回给前端了,不过在这以前咱们还要建立两个类:DomainException和SuccessResult,app
package com.xfind.exception; import com.xfind.util.result.ResultCode; public class DomainException extends RuntimeException { private int errCode = ResultCode.Unknown_Exception.getCode(); public DomainException() { super(ResultCode.Unknown_Exception.getMessage()); } public DomainException(ResultCode resultCode) { super(resultCode.getMessage()); this.errCode = resultCode.getCode(); } public int getErrCode() { return errCode; } public void setErrCode(int errCode) { this.errCode = errCode; } }
DomainException的做用是要抛出的异常类,从代码中能够看出它是继承RuntimeException类的,因此可使用throw new DomainException(ResultCode.XX);这样就能够抛到前端。dom
package com.xfind.util.result; public class SuccessResult<T> extends Result<T> { public SuccessResult(){ } public SuccessResult(T data) { super(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data); } }
这个类的做用是辅助类,把Code和Message都封装到这个类,就能够直接返回到前端了。测试
咱们再添加一个GlobalExceptionHandler类,来处理每一个抛出DomainException类返回的数据,前返回Result给前端了,以下所示:this
/** * 统一异常处理 */ @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(value = DomainException.class) public Result domainExceptionHandler(HttpServletRequest req, DomainException e) throws Exception { e.printStackTrace(); Result result = new Result(e.getErrCode(), e.getMessage()); return result; } }
如今咱们编写一个类来测试咱们刚刚写的类的运行状况,以下所示阿里云
@GetMapping("/isRegister") public ResponseEntity isRegister(@RequestParam String user) { boolean has_phone = smsService.isExist(user); if (has_phone) { throw new DomainException(ResultCode.PHONE_EXIST); } boolean has_email = emailService.isExist(user); if (has_email) { throw new DomainException(ResultCode.EMAIL_EXIST); } String str = "该手机号或者邮箱没有被注册,能够注册本系统"; Result result = new SuccessResult<>(str); return ResponseEntity.ok(result); }
该方法是判断用户是否已经被注册,方法里面先判断是否有相同手机或者邮箱,若是有就招聘异常给前端,不然则返回正确信息给前端,咱们使用POSTMan来测试下
1)首先咱们输入一个已经存在的手机号spa
2)咱们再输入一个已经存在的邮箱3d
3)咱们再输入一个不存在存在的手机
一、首先创建一个错误码和错误消息类,而后再把消息返回,返回的时候要设置成JSON抛给前端二、我这里的消息码使用的是int,你也能够设置成String,这个看你需求了