资讯专栏INFORMATION COLUMN

前后端分离项目 — Java后台统一错误消息处理

rockswang / 757人阅读

摘要:前言一般我们后台出错报都是直接抛出来的,但是微信公众号,或者支付宝支付等等,他们的异常都有错误码对应错误信息,他们是如何根据错误信息展示对应的错误码提供给前端的呢,这也就是我们要说的统一错误消息处理机制。

1、前言

一般我们后台出错报Exception都是直接抛出来的,但是微信公众号,或者支付宝支付等等,他们的异常都有错误码对应错误信息,他们是如何根据错误信息展示对应的错误码提供给前端的呢,这也就是我们要说的统一错误消息处理机制。

2、Java实现

首先创建一个Result类,这个类作用是设置消息码以及消息文本还有消息数据,如下所示

package com.xfind.util.result;

public class Result {
    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,

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);这样就可以抛到前端。

package com.xfind.util.result;


public class SuccessResult extends Result {
    public SuccessResult(){

    }

    public SuccessResult(T data) {
        super(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
    }
}

这个类的作用是辅助类,把Code和Message都封装到这个类,就可以直接返回到前端了。

3、设置统一异常处理

我们再添加一个GlobalExceptionHandler类,来处理每个抛出DomainException类返回的数据,前返回Result给前端了,如下所示:

/**
 * 统一异常处理
 */
@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;
    }
}
4、测试

现在我们编写一个类来测试我们刚刚写的类的运行情况,如下所示

@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)首先我们输入一个已经存在的手机号

2)我们再输入一个已经存在的邮箱

3)我们再输入一个不存在存在的手机

5、总结

1、首先建立一个错误码和错误消息类,然后再把消息返回,返回的时候要设置成JSON抛给前端
2、我这里的消息码使用的是int,你也可以设置成String,这个看你需求了

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/77359.html

相关文章

  • 2014 杭JS大会 会议盛况与技术热点现场报道(直播)

    摘要:中国开发者的年度盛会中国开发者大会,于年月日在杭州举办了本年度的杭会议我们的和将为在现场为您带来现场的报道,一览大牛风采,直击技术热点。签到中第日的会议即将开幕以下是与参会者和与博文视点的作者们合影 中国JS开发者的年度盛会JS中国开发者大会,于2014年6月21日在杭州举办了本年度的杭JS会议! 我们SegmentFault的 @integ 和 @shamiao 将为在现场为您带来...

    caige 评论0 收藏0
  • 两年了,我写了这些干货!

    摘要:开公众号差不多两年了,有不少原创教程,当原创越来越多时,大家搜索起来就很不方便,因此做了一个索引帮助大家快速找到需要的文章系列处理登录请求前后端分离一使用完美处理权限问题前后端分离二使用完美处理权限问题前后端分离三中密码加盐与中异常统一处理 开公众号差不多两年了,有不少原创教程,当原创越来越多时,大家搜索起来就很不方便,因此做了一个索引帮助大家快速找到需要的文章! Spring Boo...

    huayeluoliuhen 评论0 收藏0
  • 前后分离的问题与解决方案

    摘要:版本升级每个文件方法头标明版本号,每次修改需修改版本号大于原版本号,即为版本升级。 这些天项目有的API出现版本控制问题,着实忙乎了一小阵,因为项目使用TP5的传统方法进行版本控制(api目录下进行版本区分,由请求路径决定使用的版本) showImg(https://segmentfault.com/img/bVbekSM?w=200&h=128); 但是问题往往是,项目使用了v2版本...

    zilu 评论0 收藏0
  • Spring Boot + Vue 前后分离开发,前网络请求封装与配置

    摘要:今天松哥就带大家来看看的使用。此时启动前端项目,就可以顺利发送网络请求了。松哥将自己封装的网络请求库已经放在上,欢迎大家参考。前端网络访问,主流方案就是 Ajax,Vue 也不例外,在 Vue2.0 之前,网络访问较多的采用 vue-resources,Vue2.0 之后,官方不再建议使用 vue-resources ,这个项目本身也停止维护,目前建议使用的方案是 axios。今天松哥就带大...

    Ku_Andrew 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<