spring boot统一接口返回及全局异常处理-mile米乐体育

目录

  • 1、mile米乐体育的解决方案
  • 2、具体实现
    • 2.1 定义状态码统一接口
    • 2.2 公共模块状态码枚举类
    • 2.3 定义全局自定义异常
    • 2.4 定义统一接口格式输出类
    • 2.5 定义统一接口格式输出类
    • 2.6 接口统一输出优化
    • 2.7 子系统如何实现
  • 3、子系统定义状态码,实现baseresultcode接口

前言:

前段时间接手了一个老项目,现在需要在此项目中添加一些新的需求,同事在开发过程中遇到了一些问题?

  • 1.成功的状态到底是200还是0啊,订单系统200代表成功,而会员系统却是0代表成功。
  • 2.接口返回的结果中,有些是用msg字段表示描述,有些又是用desc字段描述,前段处理起来比较麻烦能不能统一。
  • 3.错误提示信息需要支持国际化。

其实这些问题,归根究底还是代码规范问题,我们需要将接口定义和全局异常统一处理,历史项目10多个工程,难道每个工程都去实现一遍,答案可定是不可能的。

1、mile米乐体育的解决方案

定义公共模块,实现统一接口定义规范和异常处理,其他的系统进行依赖和扩展即可。

2、具体实现

2.1 定义状态码统一接口

public interface baseresultcode { /** * 状态码 * @return */ int getcode(); /** * 提示信息 * @return */ string getmsg(); }

2.2 公共模块状态码枚举类

public enum resultcode implements baseresultcode { ok(200, "成功"), error(300,"系统异常"), need_auth(301, "非法请求,请重新登录"), paramter_error(302, "参数错误"); //省略其他定义错误码 private int code; private string msg; private resultcode(int code, string msg) { this.code = code; this.msg = msg; } public static resultcode getvalue(int code) { for (resultcode errorcode : values()) { if (errorcode.getcode() == code) { return errorcode; } } return null; } //省略get、set方法 }

2.3 定义全局自定义异常

public class sysexception extends runtimeexception { private static final long serialversionuid = 5225171867523879342l; private int code; private string msg; private object[] params; private baseresultcode errorcode; public sysexception() { super(); } public sysexception(string message) { super(message); } public sysexception(throwable cause) { super(cause); } public sysexception(int code ,string message) { this.code = code; this.msg = message; } public sysexception(int code ,string message, object[] params) { this(code, message); this.params= params; } public sysexception(string message, throwable cause) { super(message, cause); } public sysexception(baseresultcode errorcode) { this.errorcode = errorcode; } public sysexception(string message, object[] params) { super(message); this.params = params; } public sysexception(baseresultcode errorcode, string message, object[] params) { this(message, params); this.errorcode = errorcode; } /** * construct by default * *@param message * message * @param parameters * parameters * @param cause * cause */ public sysexception(string message, object[] params, throwable cause) { super(message, cause); this.params = params; } public int getcode() { return code; } public void setcode(int code) { this.code = code; } public string getmsg() { return msg; } public void setmsg(string msg) { this.msg = msg; } /** * @return the params */ public object[] getparams() { return params; } /** * @param params * the params to set */ public void setparams(object[] params) { this.params = params; } public baseresultcode geterrorcode() { return errorcode; } public void seterrorcode(baseresultcode errorcode) { this.errorcode = errorcode; } }

2.4 定义统一接口格式输出类

public class result implements serializable { private static final long serialversionuid = -1773941471021475043l; private object data; private int code; private string msg; public result() { } public result(int code, object data, string msg) { this.code = code; this.data = data; this.msg = msg; } public result(int code, string desc) { this(code, null, desc); } public result(baseresultcode errorcode) { this(errorcode.getcode(), null, errorcode.gettxofpplzumsg()); } public static result success() { return success(null); } public static result success(object data) { result result = new result(); result.setdata(data); result.setcode(resultcode.ok.getcode()); return result; } public static result error(string msg) { result result = new result(); result.setcode(resultcode.error.getcode()); result.setmsg(msg); return result; } public static result error(baseresultcode basecode) { result result = new result(); result.setcode(basecode.getcode()); result.setmsg(basecode.getmsg()); return result; } }

个人建议:统一接口输出类不要定义为泛型类型

2.5 定义统一接口格式输出类

@restcontrolleradvice public class sysexceptionhandler { public static log logger = logmanager.getlogger(sysexceptionhandler.class); @exceptionhandler(exception.class) public result handleexception(httpservletrequest request, exception ex) { logger.error("handle exception恰卡编程网 request url:{},exception:{}",request.getrequest,ex); result result = new result(); //系统异常 if (ex instanceof sysexception) { sysexception se = (sysexception) ex; baseresultcode resultcode =se.geterrorcode(); if(resultcode==null) { result = result.error(se.getmessage()); } else { result = new result(resultcode.getcode(), stringutil.isnotempty(se.getmessage())?se.getmessage():resultcode.getmsg()); } } //参数错误 else if (ex instanceof constraintviolationexception) { constraintviolationexception v = (constraintviolationexception) ex; string message = v.getconstraintviolations().iterator().next() .getmessage(); result.setcode(resultcode.paramter_error.getcode()); result.setmsg(resultcode.paramter_error.getmsg() ":" message); } //参数错误 else if (ex instanceof bindexception) { bindexception v = (bindexception) ex; string message = v.getallerrors().stream().map(objecterror::getdefaultmessage).collect(collectors.joining(",")); result.setcode(resultcode.paramter_error.getcode()); result.setmsg(resultcode.paramter_error.getmsg() ":" message); } //参数错误 else if (ex instanceof methodargumentnotvalidexception) { methodargumentnotvalidexception v = (methodargumentnotvalidexception) ex; string message = v.getbindingresult().getallerrors().stream().map(objecterror::getdefaultmessage).collect(collectors.joining(",")); result.setcode(resultcode.paramter_error.getcode()); result.setmsg(resultcode.paramter_error.getmsg() ":" message); } else { result = new result(resultcode.error.getcode(),exceptionutil.geterrormsg(ex)); } logger.info("exception handle reuslt:" result); return result; } }

上述定义已经可以实现全局接口和异常的统一处理,但是存在的如下问题

每个controller都需要返回reesult类型,且每个方法都需要返回result.success()或者result.success(data)的结果,有点重复,需要进行优化。

@getmapping("adduser") public result add() { for(int i=0;i<10;i ) { tuser user = new tuser(); //user.setoid(idworker.getid()); user.setname("shareing_" i); user.setage(i); userservice.adduser(user); } return result.success(); }

2.6 接口统一输出优化

实现方式只需要实现responsebodyadvice接口,重写beforebodywrite方法接口。

@restcontrolleradvice public class responseadvice implements responsebodyadvice

网站地图