【314期】Spring Cloud OpenFeign 接口反序列化失效,该如何解决?
点击上方“Java精选”,选择“设为星标”
别问别人为什么,多问自己凭什么!
下方有惊喜,留言必回,有问必答!
每一天进步一点点,是成功的开始...
1. 关于 Spring Boot 无侵入式API接口统一格式,变得具有侵入性的那回事
19年发布了《Spring Boot 无侵入式 实现API接口统一JSON格式返回》,得到的广泛的转载,同时也在Spring Boot多个项目进行了实践操作,得到大家一致好评。
可是最近几年随着Spring Cloud的流行,我发现基于ResponseBodyAdvice
在Spring Cloud OpenFeign
的继承模式下 具有了侵入性
,而且侵入性还很强大,还导致resfulAPI接口反序列化出现失败的问题(哈哈哈,挖坑了很对不起大家)。
既然发现了问题,那就好好解决一下吧,解决方式有多种,至于选择就看大家喜欢了吧
return object
, 简单轻松和谐return Result<?>
,简单轻松和谐,但是client需要 调用Result.getData()方法feign.codec.Decoder
不轻松,需要自己去自定义Decoder规则另外,关于Springcloud面试题,公众号Java精选,回复java面试,获取关于springcloud更多面试题资料。
第一方案和第二方案都是硬编码,没有多少可延展性可说的,现在我们就把feign.codec.Decoder
如何解决这种侵入性的问题解决了吧,其实也没有多少东西可说的,就说说第三方案是如何解决的吧,就是为了填坑罢了
2. Decoder解决ResponseBodyAdvice的侵入性
使用 Spring Cloud 2021.0.1
Decoder的使用百度上面一大堆,我就不展开说了
/**
* 定义 各种不同情况下对
* @author changjin wei(魏昌进)
* @since 2022/4/8
*/
public interface UserService {
/** 原生 ResponseBody返回 */
@RequestMapping(method = RequestMethod.GET, value = "/users/{id}")
User getUser(@PathVariable("id") long id);
/** 自定义 ResultResponseBody 统一返回 */
@RequestMapping(method = RequestMethod.GET, value = "/Resultv1")
@ResultResponseBody
User getResultv1();
/** 硬编码 Result<User> 返回同时带上ResultResponseBody统一返回 */
@RequestMapping(method = RequestMethod.GET, value = "/Resulv2")
@ResultResponseBody
Result<User> getResultv2();
}
Decoder
对Result
进行解析
/**
* @author changjin wei(魏昌进)
* @since 2022/4/8
*/
public class ResultDecoder implements Decoder {
private Decoder decoder;
public ResultDecoder(Decoder decoder) {
this.decoder = decoder;
}
@Override
public Object decode(Response response, Type type) throws IOException, FeignException {
Method method = response.request().requestTemplate().methodMetadata().method();
boolean isResult = method.getReturnType() != Result.class && method.isAnnotationPresent(ResultResponseBody.class);
if (isResult) {
ParameterizedTypeImpl resultType = ParameterizedTypeImpl.make(Result.class, new Type[]{type}, null);
Result<?> result = (Result<?>) this.decoder.decode(response, resultType);
return result.getData();
}
return this.decoder.decode(response, type);
}
}
另外,推荐下Spring cloud的通用微服务开源项目:
https://gitee.com/yoodb/jingxuan-springcloud
注册ResultDecoder
到feign
中
/**
* @author changjin wei(魏昌进)
* @since 2022/4/8
*/
@Configuration(proxyBeanMethods = false)
public class FeignConfiguration {
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
public Decoder feignDecoder(ObjectProvider<HttpMessageConverterCustomizer> customizers) {
return new OptionalDecoder(new ResponseEntityDecoder(new ResultDecoder(new SpringDecoder(this.messageConverters, customizers))));
}
}
这样子就解决了在Spring Boot中无侵入性,但是在Spring Cloud中具有侵入性的问题,没有多少技术含量的,纯属为了填坑。
作者:小魏小魏我们去那里呀
https://blog.csdn.net/qq_34347620/article/details/102239179
公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!
3000+ 道各类技术面试题在线刷,最新、最全 Java 面试题!
【306期】微服务 Spring Cloud 架构实现分布式日志采集方案
【308期】Java 实现 10 万,并发去重,优雅地处理重复请求!
【310期】Spring Cloud 分布式 WebSocket 集群解决方案
最近有很多人问,有没有读者交流群!想知道如何加入?方式很简单,兴趣相投的朋友,只需要点击下方卡片,回复“加群”,即可无套路入交流群!