目前用 @RestControllerAdvice 封装了统一响应,包上了 success 、code 等统一响应。
A 服务通过 feign 调用 B 服务后获取的结果中,也包上了这个响应,如何统一的去除通过 feign 调用而包装的统一响应呢?让获取到的结果可以直接使用
1
devswork 2021-11-23 15:51:08 +08:00
写个解析 tool 类不就行了,顺便还能 check 一下 code
|
2
xwayway 2021-11-23 16:01:49 +08:00
当初让你卷八股文你不肯,现在游泳了吧。来来来,设计模式来一波,今天你用 openfeigin ,明天用纯 httpclient ,后天用 resttemplate 。这个时候应该加上一个中介者,来减少具体调用执行层和调用方之间的耦合,同时可以将 success ,code 这些统一格式的解析放到这个中介者里面来,中介者返回给调用方的就是纯纯的业务对象
|
3
securityCoding 2021-11-23 16:11:06 +08:00
openfeign 支持泛型反序列化的,为什么要去掉呢?
|
4
BBCCBB 2021-11-23 16:37:31 +08:00
feign 有 Decoder, 你可以实现自己的 Decoder 来处理. 不过你这个做法不太好..
直接 1 楼的方式, 写个 Util 方法来 unwrap 咯. |
5
amoyiki 2021-11-23 17:31:43 +08:00
写个工具类即可
```java public static <T> List<T> getFeignDataList(Callable<RspResult> feignFunc, Class<T> clazz) throws Exception { RspResult ret = feignFunc.call(); if (ret.getCode() == 200) { // 判断是否是有 items 数组,有的话取出 items 后在进行反序列化 List<T> ts = null; String s = JsonUtils.objectToJson(ret.getData()); if (!StringUtils.isEmpty(s) && s.contains("items")) { Map map = JsonUtils.objectToPojo(ret.getData(), Map.class); ts = JsonUtils.objectToList(map.get("items"), clazz); } else { ts = JsonUtils.objectToList(ret.getData(), clazz); } return ts; } return null; } ``` |
6
xuanbg 2021-11-23 18:40:24 +08:00
在网关上通过拦截器封装,所以内部调用获取到的 body 就是纯粹的数据。
|
7
zzl22100048 2021-11-23 20:47:32 +08:00 via iPhone
想统一封装从网关入手
|
8
bigbyto 2021-11-24 00:13:34 +08:00 1
贴一个我自己用的方案吧,这个的缺点是 Response 如果是非成功状态抛出异常是会被 feign 捕获包装重新抛出,里面包含了 decode 的信息。
public class AutoBoxingDecoder implements Decoder { private final SpringDecoder delegate; public AutoBoxingDecoder(SpringDecoder decoder) { this.delegate = decoder; } @Override public Object decode(Response response, Type type) throws IOException, FeignException { if (type instanceof NormalResponse) { return delegate.decode(response,type); } else if (type instanceof ParameterizedType) { ParameterizedType t = (ParameterizedType) type; if (t.getRawType() instanceof NormalResponse) { return delegate.decode(response,type); } } ParameterizedType pt = new MyParameterizedType(type); Object object = delegate.decode(response,pt); if (object instanceof NormalResponse) { return unpackOrThrow((NormalResponse<?>) object); } return object; } private Object unpackOrThrow(NormalResponse<?> res) { if (res == null) { throw new AppException("client response body is empty."); } if (!res.isSuccess()) { throw new AppException(res.getMessage()); } return res.getData(); } static class MyParameterizedType implements ParameterizedType { private final Type argument; MyParameterizedType(Type argument) { this.argument = argument; } @Override public Type[] getActualTypeArguments() { return new Type[]{argument}; } @Override public Type getRawType() { return NormalResponse.class; } @Override public Type getOwnerType() { return null; } } } |
9
Geekerstar OP @xuanbg feign 内部调用的,不走网关吧?
|
10
xuanbg 2021-11-24 10:31:07 +08:00
@Geekerstar 对呀,不走网关所以就没有封装呀。
|
11
9c04C5dO01Sw5DNL 2022-01-18 00:30:27 +08:00
刚好之前做了一点工作。主要是 decoder ,contract 参考`https://github.com/giiiiiithub/web-components/tree/master/feign-client/src/main/java/com/jj/web/feign/client`
|
12
xinQing 2022-01-28 16:12:44 +08:00
我也遇到过这样的,我是跟 8 楼一样的做法,搞个自定义 decoder 去拆包,如果发现错误就统一抛出,正常就拆包后,根据返回对象反序列化。
|