参考文档:
1.https://www.jianshu.com/p/d2cb1355653c
2.http://c.biancheng.net/view/1100.html
3.https://blog.csdn.net/sihai12345/article/details/81070174
java web项目,就每次的用户请求,服务器总会做出相应,当进行顺利时直接返回数据,当进行错误时要返回错误信息。这些错误信息尽管种类比较多,但是仍然可以将他们归类列举出来。这种做法虽然不一定是必要的,但是可以使程序显得更加系统化。
比如,我希望出现错误,返回给前端的结果是这样的:
{
"code":"fail",
"msg":"用户注册失败",
"data":{"description":"插入一条数据出错","code":1000}
}
它包含的信息有:
"code":"fail",表示客户调用请求的获取数据的目的并没达到;
"msg":"用户注册失败",明确地表示业务执行情况;
"data":{"description":"插入一条数据出错","code":1000},表明数据库底层实现的详细信息。
我将使用enum 枚举的就是data 对应的内容。
public interface BaseErrorInfoInterface {
//获取code
public Integer getCode();
//获取描述
public String getDescription();
}
public enum ErrorEnum implements BaseErrorInfoInterface{
/*sql错误*/
InsertErr(1000,"插入一条数据出错"),
SearchOneErr(1001,"想查询一条数据,结果查找到多条"),
UpdateErr(1002,"修改一条,结果修改了多条"),
/*用户请求错误*/
SignNull(2000,"签名为空"),
SignErr(2001,"签名不匹配"),
LoginTimeOut(2002,"登录超时"),
ArgumentsErr(2003,"参数有误"),
RedundantOperation(2004,"无效的操作"),/*例如,试图添加两个相同的对象,而该操作不被系统允许*/
/*系统错误*/
NullPointer(3001,"空指针异常"),
UnknownErr(3002,"系统繁忙");
// 以上是枚举的成员,必须先定义,而且使用分号结束
private final String description;
private final int code;
ErrorEnum(int code,String description) {
this.description = description;
this.code=code;
}
//获取code
@Override
public Integer getCode(){
return code;
}
//获取描述
@Override
public String getDescription(){
return description;
}
//返回json 详细描述
public Map Description() {
Map map= new HashMap<>();
map.put(String.valueOf(code),description);
JSONObject json = (JSONObject) JSONObject.toJSON(map);
return json;
}
//返回map 详细描述
public Map DescriptionMap() {
Map map= new HashMap<>();
map.put(String.valueOf(code),description);
return map;
}
//根据code获取描述
public static Map getDescriptionByCode(Integer code) {
ErrorEnum[] values = ErrorEnum.values();
for (ErrorEnum value : values) {
if (value.code == code) {
Map map = new HashMap();
map.put(String.valueOf(value.code),value.description);
return map;
}
}
return null;
}
}
InsertErr(1000,"插入一条数据出错"),
SearchOneErr(1001,"想查询一条数据,结果查找到多条")。
等类似是:
private final static ErrorEnum InsertErr = InsertErr(1000,"插入一条数据出错");
类似实例化一个对象然后赋值给一个final static 的ErrorEnum类型变量。
构造函数:
private final String description;
private final int code;
ErrorEnum(int code,String description) {
this.description = description;
this.code=code;
}
其中ErrorEnum(int code,String description)构造函数默认且只能是private。
private final String description;final修饰的变量没初始化,也没报错,不知道具体原因。
然后,在枚举类里面定义的所有方法如 getCode(),getDescription()等,所有的实例化一个对象
如InsertErr(1000,"插入一条数据出错") 等都可以调用。
step3 数据的统一返回类型
/**返回数据封装*/
@Data
public class ResultData {
private String code;//状态码,success,fail
private String msg="";//错误提示,仅fail有内容
private Object data;//返回数据
private Long count;//集合数目,分页时使用,返回总条数
//自定义code
public static ResultData success(Object data,String code) {
ResultData result = new ResultData();
result.setCode(code);
result.setMsg(null);
result.setData(data);
result.setCount(null);
return result;
}
public static ResultData success(Object data) {
ResultData result = new ResultData();
result.setCode("success");
result.setMsg(null);
result.setData(data);
result.setCount(null);
return result;
}
public static ResultData success(Object data,Long count) {
ResultData result = new ResultData();
result.setCode("success");
result.setMsg(null);
result.setData(data);
result.setCount(count);
return result;
}
public static ResultData error(String msg) {
ResultData result = new ResultData();
result.setCode("fail");
result.setMsg(msg);
result.setData(null);
return result;
}
public static ResultData error(String msg, Object data) {
ResultData result = new ResultData();
result.setCode("fail");
result.setMsg(msg);
result.setData(data);
return result;
}
public static ResultData error(String msg, BaseErrorInfoInterface baseErrorInfoInterface) {
ResultData result = new ResultData();
result.setCode("fail");
result.setMsg(msg);
Map map = new HashMap();
map.put("description",baseErrorInfoInterface.getDescription());
map.put("code",baseErrorInfoInterface.getCode());
result.setData(map);
return result;
}
}
step4 使用创建的枚举类
@Test
public void method01() {
System.out.println( ErrorEnum.ArgumentsErr.Description());//{"2003":"参数有误"}
System.out.println(JSON.toJSON(ErrorEnum.getDescriptionByCode(2002)));//{"2002":"登录超时"}
System.out.println(ErrorEnum.LoginTimeOut.getCode());//2002
System.out.println(ErrorEnum.LoginTimeOut.getDescription());//登陆超时
//类:com.example.studyspringboot.studyboot.utils.stuEnum.Main 方法名:method01 行号:18
System.out.println(MarkLine.getLineNumber());
//{"msg":"用户注册失败","code":"fail","data":{"description":"插入一条数据出错","code":1000}}
System.out.println(JSON.toJSON(ResultData.error("用户注册失败",ErrorEnum.InsertErr)));
// ResultData res = ResultData.error("用户注册失败", ((Function) errorEnum -> {
// System.out.println(MarkLine.getLineNumber());
// return errorEnum;
// }).apply(ErrorEnum.InsertErr));
// System.out.println(JSON.toJSON(res));
}
其中MarkLine.getLineNumber()用来获取错误的位置。最好是将其输入到log.txt中。MarkLine是比较简单的,如下
public class MarkLine {
public static String getLineNumber() {
int level = 1;
StackTraceElement[] stacks = new Throwable().getStackTrace();
int lineNumber = stacks[level].getLineNumber();
String className = stacks[level].getClassName();
String methodName = stacks[level].getMethodName();
return "类:"+className+" 方法名:"+methodName+" 行号:"+String.valueOf(lineNumber);
}
}