Spring Cloud OpenFeign 接口反序列化失效,该怎么解决?

Posted Java知音_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud OpenFeign 接口反序列化失效,该怎么解决?相关的知识,希望对你有一定的参考价值。

点击关注公众号,实用技术文章及时了解

来源:blog.csdn.net/qq_34347620/article/

details/124295302

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

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

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

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

  1. return object, 简单轻松和谐

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

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

第一方案和第二方案都是硬编码,没有多少可延展性可说的,现在我们就把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);
    

注册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中具有侵入性的问题,没有多少技术含量的,纯属为了填坑

推荐

主流Java进阶技术(学习资料分享)

Java面试题宝典

加入Spring技术开发社区

PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。点“在看”支持我们吧!

以上是关于Spring Cloud OpenFeign 接口反序列化失效,该怎么解决?的主要内容,如果未能解决你的问题,请参考以下文章

spring cloud openFeign传参的一些总结(有错,待更新)

java springboot 引用openfeign 接口转发

Spring Cloud OpenFeign

Spring Cloud OpenFeign

Spring Cloud ( openFeign 服务发现配置公共client抽取 )

Spring Cloud OpenFeign文档