查看原文
其他

【314期】Spring Cloud OpenFeign 接口反序列化失效,该如何解决?

Java精选 2022-08-09

点击上方“Java精选”,选择“设为星标”

别问别人为什么,多问自己凭什么!

下方有惊喜,留言必回,有问必答!

每一天进步一点点,是成功的开始...

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规则
  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精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!

------ THE END ------

精品资料,超赞福利!

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


3000+ 道各类技术面试题在线刷,最新、最全 Java 面试题!

期往精选  点击标题可跳转

【305期】Spring Cloud 优雅下线+灰度发布

【306期】微服务 Spring Cloud 架构实现分布式日志采集方案

【307期】从实现原理来讲,Nacos 为什么这么强?

【308期】Java 实现 10 万,并发去重,优雅地处理重复请求!

【309期】Spring Bean 容器启动耗时统计分析

【310期】Spring Cloud 分布式 WebSocket 集群解决方案

【311期】4种方法,实现多线程按照指定顺序执行

【312期】天坑!常见的 update 语句很容易造成 Bug 问题

【313期】SpringBoot 无侵入式,实现 API 返回统一 JSON 格式

 技术交流群!

最近有很多人问,有没有读者交流群!想知道如何加入?方式很简单,兴趣相投的朋友,只需要点击下方卡片,回复“加群”,即可无套路入交流群!

文章有帮助的话,在看,转发吧!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存