项目里面一直在用 gson 来序列化对象,最近在接一家第三方 api 。
如果请求出错,对方响应类似:
{"code":-1021,"msg":"Timestamp for this request is outside of the recvWindow."}
请求正确,对方响应:
{
"feeTier": 0,
"updateTime": 0,
"assets": [{
"asset": "XXX",
"updateTime": 0
}],
"positions": [{
"symbol": "XXX",
"initialMargin": "0",
"maintMargin": "0"
}]
}
我自己构造了 2 个对象的 Pojo ,一个是 ResponseError ,一个是 Response
if( httpResponse.contains("code\":-1021")){
ResponseError resp = GSON.fromJson( httpResponse, ResponseError.class);
}else{
Response resp = GSON.fromJson( httpResponse, Response.class);
}
不知道有没有更好的写法,能够定义一个更好的: 1 ,让我能够不先用 string 来判断。。。 2 ,最好 2 个响应的序列化的对象可以怎样继承一下,统一的返回给上层。。。
1
qping 2022-08-25 13:12:35 +08:00
正则先 match 下?
|
2
JxQg597 2022-08-25 13:18:57 +08:00
对方的返回接口不标准,你的接受实体也没办法标准化抽象。
1.用一个 Response 接收返回值,包含错误响应的 code,msg ,也包含正确响应的所有返回值。 2.响应直接解析成 Response ,并作解析异常捕获,并抛出异常信息。 3.根据 code 是否为 null 来判断请求是否错误,并抛出异常信息。 4.最后直接 return Response |
3
bk201 2022-08-25 13:29:45 +08:00
直接解析 json object 通过 path 拿自己需要的值,放入自己定义的标准 vo 里,返回给内部使用者
|
4
superliy 2022-08-25 13:38:24 +08:00
把出错的请求字段放到 abstract response 里,其他正确的 response 继承,这样都只要返回 response 就行,使用时判断 code
|
5
jiajianjava 2022-08-25 13:48:09 +08:00
{
"code":200, "msg": "", "feeTier": 0, "updateTime": 0, "assets": [{ "asset": "XXX", "updateTime": 0 }], "positions": [{ "symbol": "XXX", "initialMargin": "0", "maintMargin": "0" }] } 直接合并,定义这样是不是就好了? |
6
dreamramon OP @jiajianjava #5
@JxQg597 #2 主要是他正确的响应,他有几十个 api ,就有几十个格式。。。 我们现在有 ResponseError.class, ResponseA.class, ResponseB.class 然后有的时候,因为对方 api 不稳定,请求有需要重试。。。 以前,只需要在我们封装的 HttpUtil 里面根据网络状态或者 http 状态码自动重试,业务层不操心了。。。 但是现在这家,需要在业务层重试。。。所以说,想能不能有个统一的手段,能解析成一个 response ,然后根据里面某个值的判断,再分开能拿到 ResponseA 或者 ResponseB 。 |
7
fgwmlhdkkkw 2022-08-25 14:54:23 +08:00
try,catch
|
8
JxQg597 2022-08-25 15:24:04 +08:00
@dreamramon #6
```java class ResponseBase{ String code, String msg } class XXXResponse extends ResponseBase{ xxx, xxx, xxx } XXXResponse getXXX(AtomicInteger retriesNum){ if (retriesNum==null ) retriesNum = new AtomicInteger(0); XXXResponse response = doGet(); if(response.getcode !=null){ log.error; int currentNum = retriesNum.getAndIncrement(); if(currentNum>configRetriesNum) throw Exception; #需要延迟 sleep? return getXXX(retriesNum); } return response ; } ``` |
9
JNotEnoughW 2022-08-25 15:43:16 +08:00
自己包装一层转换器,提前校验是否有 "code",组装成统一格式返回
{ "code":200, "msg":"", "data":xxx } |
10
sunjiayao 2022-08-25 15:48:19 +08:00
https://gist.github.com/sunluman/b49e12aa3e4f76390fbc08504ef38345
只能通过有哪些 key 来区分用什么实体类型?可以先类似这样封装下,然后怒喷下对面 |
11
oneisall8955 2022-08-25 23:15:02 +08:00 via Android
造轮子的时间到了,最近对接某平台也这样,不过会有固定 code 表示请求失败和正确
|
12
dreamramon OP @JxQg597 #8
谢谢大神。。。我的想法是有没有可能,可以写一个统一的父累。 Response resp = GSON.fromJson( httpResponse, Response.class); 然后 return 这个 resp 给到业务的方法,然后业务的方法拿到了这个 resp ,可以根据里面的 code 来判断是否出错,并且解析出自己的 ResponseA ,或者 ResponseB? 比如: 业务 A: if (resp.code==null) { ResponseA respA= (ResponseA) resp.data; }else if (resp.code == -1021) { //retry logic } 业务 B: 业务 A: if (resp.code==null) { ResponseB respB= (ResponseB) resp.data; } else if (resp.code == -1021) { //业务 B -1021 不重试 } else if (resp.code == -1001) { //业务 B -1001 重试,下面自己实现重试逻辑 } |
13
JxQg597 2022-08-26 17:18:21 +08:00
@dreamramon #12 可以参考 9 楼的做法,做成标准 Response<T>,解析两次 Json ,需要用到泛型。
```java Class Response<T>{ private String code; private String msg; private T data; public Response<T>(T data){ this.data = data; } } public <T> Response<T> invokeGet(XXXQuery query, Class<T> tClass){ try{ String responseJson = doGet(query); Response response = JSONUtil.toBean(responseJson,Response.class); if(StrUtil.isNotEmpty(response.getCode())){ return response; } T datd = JSONUtil.toBean(responseJson,tClass); return new Response<T>(data); }catch(AnyException e){ log.error; throw new BussniessException(); } } ``` |