面试官问:Spring Cloud OpenFeign接口反序列化失效,该如何解决?

1. 关于 SpringBoot无侵入式API接口统一格式,变得具有侵入性的那回事

之前发布了《Spring Boot 无侵入式 实现API接口统一JSON格式返回》,得到的广泛的转载,同时也在Spring Boot多个项目进行了实践操作,得到大家一致好评。

可是最近几年随着Spring Cloud的流行,我发现基于ResponseBodyAdviceSpring Cloud OpenFeign的继承模式下 具有了侵入性,而且侵入性还很强大,还导致resfulAPI接口反序列化出现失败的问题(哈哈哈,挖坑了很对不起大家)。

既然发现了问题,那就好好解决一下吧,解决方式有多种,至于选择就看大家喜欢了吧!

推荐划水摸鱼地址:

https://www.yoodb.com/slack-off/home.html

  1. return object, 简单轻松和谐

  2. return Result<?> ,简单轻松和谐,但是client需要 调用Result.getData()方法

  3. feign.codec.Decoder 不轻松,需要自己去自定义Decoder规则

  4. 另外,关于Springcloud面试题,公众号Java精选,回复java面试,获取关于springcloud更多面试题资料。

第一方案和第二方案都是硬编码,没有多少可延展性可说的,现在我们就把feign.codec.Decoder如何解决这种侵入性的问题解决了吧,其实也没有多少东西可说的,就说说第三方案是如何解决的吧,就是为了填坑罢了

2. Decoder解决ResponseBodyAdvice的侵入性

使用 Spring Cloud 2021.0.1

Decoder的使用百度上面一大堆,我就不展开说了

定义feignService api接口, 因为篇幅问题,我们就忽略 Controller实现和client调用了

/**
 * 定义 各种不同情况下对
 * @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();
}

DecoderResult进行解析

/**
 * @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

注册ResultDecoderfeign

/**
 * @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精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!
最近有很多人问,有没有读者交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!

🔥Java精选面试题🔥:3000+道面试题,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计等,在线随时刷题!
------ 特别推荐 ------
特别推荐:专注分享最前沿的技术与资讯,为弯道超车做好准备及各种开源项目与高效率软件的公众号,「大咖笔记」,专注挖掘好东西,非常值得大家关注。点击下方公众号卡片关注。

点击“阅读原文”,了解更多精彩内容!文章有帮助的话,点在看,转发吧!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值