SpringCloud OpenFeign自定义结果解码器方式

 更新时间:2023年09月01日 09:57:14   作者:david'fantasy  
这篇文章主要介绍了SpringCloud OpenFeign自定义结果解码器方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

SpringCloud OpenFeign自定义结果解码器

我们在定义微服务接口的时候,通常会使用一个Result类进行封装,将提示信息,返回对象和状态码等内容封装到一起返回给调用方,

例如

如下的格式:

public class Result<T> {
    /**
     * 响应码,200为成功
     */
    private Integer code;
    /**
     * 失败时的具体失败信息
     */
    private String message;
    /**
     * 失败信息是否为用户提示,如果是的话框架不会主动拦截该错误
     */
    private boolean userPrompt;
    /**
     * 响应的具体对象
     */
    private T data;
}

而调用方在使用Spring Cloud OpenFeign定义的客户端调用远程服务时,默认的解码器只能按照定义的方法返回类型对接口的返回结果进行强制转换,没办法实现一些自定义的逻辑,比如将统一返回的Result类重新拆开,仅返回对应的业务对象,或者对特定的响应码进行处理等等。

为了实现上述功能,我们就需要改造默认的Decoder。

Spring Cloud OpenFeign允许我们在定义一个Feign Client的时候,指定一个额外的配置类,比如:

@FeignClient(name = "stores", configuration = CustomizedConfiguration.class)
public interface StoreClient {
    //..
}

而这个配置类就可以作为我们的扩展点,我们可以在CustomizedConfiguration中定义一个自己的Decoder来覆盖默认的配置。

Spring Cloud对Feign的封装和默认配置可以查看官方文档

自定义的Decoder需要实现feign.codec.Decoder接口,也可以参考默认的Decoder的实现逻辑(org.springframework.cloud.openfeign.support.ResponseEntityDecoder),下面的实现可以对统一返回值Result类的拆分,并对异常返回进行处理:

public class FeignResultDecoder implements Decoder {
    @Override
    public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
        if (response.body() == null) {
            throw new DecodeException(response.status(), "没有返回有效的数据", response.request());
        }
        String bodyStr = Util.toString(response.body().asReader(Util.UTF_8));
        //对结果进行转换
        Result result = (Result) JsonUtil.json2obj(bodyStr, type);
        //如果返回错误,且为内部错误,则直接抛出异常
        if (result.getCode() != ResultCode.SUCCESS.code) {
            if (!result.isUserPrompt()) {
                throw new DecodeException(response.status(), "接口返回错误:" + result.getMessage(), response.request());
            }
        }
        return result.data;
    }
}

其中如何将response中的json转换为实际的返回类型很费了一些功夫,因为可能存在复杂的嵌套关系和泛型定义,最后才发现jackson框架已经有默认的实现了…

代码如下:

public static <T> T json2obj(String jsonStr, Type targetType) {
        try {
            JavaType javaType = TypeFactory.defaultInstance().constructType(targetType);
            return mapper.readValue(jsonStr, javaType);
        } catch (IOException e) {
            throw new IllegalArgumentException("将JSON转换为对象时发生错误:" + jsonStr, e);
        }
    }

实现了Decoder之后,只需要将其配置到CustomizedConfiguration中即可,注意如果CustomizedConfiguration添加了@Configuration的注解,则会成为Feign Client构建的默认配置,这样就不需要在每个@FeignClient注解中都去指定配置类了:

public class CustomizedConfiguration{
    @Bean
    public Decoder feignDecoder() {
        return new FeignResultDecoder();
    }
}

添加了自定义的Decoder之后,如果一个远程接口的定义是这样的:

@GetMapping("/api/user/detail")
 public Result<User> detailById(@RequestParam("id") Integer id) {
        User user = userService.getById(id);
        return ResultGenerator.genSuccessResult(user);
 }

我们定义Feign Client方法的时候,方法的返回值可以直接使用Result的泛型类型:

 @RequestMapping(value = "/api/user/detail", method = RequestMethod.GET)
 public User detailById(@RequestParam("id") Integer id)

类似的方式,我们还可以自定义Feign的Encoder,ErrorDecoder等关键配置组件。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring@Value使用获取配置信息为null的操作

    Spring@Value使用获取配置信息为null的操作

    这篇文章主要介绍了Spring@Value使用获取配置信息为null的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Spring使用aop切面编程时要给那些类加注解的实例

    Spring使用aop切面编程时要给那些类加注解的实例

    在使用切面编程时,通常需要为以下类或组件添加注解来标识它们,以便 Spring 或其他切面框架能够正确识别和处理它们,这篇文章主要介绍了Spring使用aop切面编程时要给那些类加注解,需要的朋友可以参考下
    2023-11-11
  • Spring MVC 请求参数绑定实现方式

    Spring MVC 请求参数绑定实现方式

    Spring MVC 是一个用于构建 Web 应用程序的框架,它提供了一种方便的方式来处理 HTTP 请求和响应,Spring MVC 提供了多种方式来实现请求参数绑定,本文结合实例代码给大家介绍的非常详细,需要的朋友跟随小编一起看看吧
    2023-09-09
  • Java Vector和ArrayList的异同分析及实例讲解

    Java Vector和ArrayList的异同分析及实例讲解

    在本篇文章里小编给大家整理的是一篇关于Java Vector和ArrayList的异同分析及实例讲解内容,有兴趣的朋友们可以学习参考下。
    2021-01-01
  • Java学习笔记之面向对象编程精解

    Java学习笔记之面向对象编程精解

    看名字它是注重对象的。当解决一个问题的时候,面向对象会把事物抽象成对象的概念,就是说这个问题里面有哪些对象,然后给对象赋一些属性和方法,然后让每个对象去执行自己的方法,问题得到解决
    2021-09-09
  • Springboot Mybatis Plus自动生成工具类详解代码

    Springboot Mybatis Plus自动生成工具类详解代码

    mybatis-plus 是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生,这篇文章带你使用Springboot Mybatis Plus自动生成工具类
    2021-11-11
  • java书店系统毕业设计 用户模块(3)

    java书店系统毕业设计 用户模块(3)

    这篇文章主要介绍了java书店系统毕业设计,第三步系统总体设计,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • Java MyBatis框架环境搭建详解

    Java MyBatis框架环境搭建详解

    MyBatis本是apache的一个开源项目iBatis,MyBatis环境的搭建有点麻烦,本章带你了解搭建过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
    2022-08-08
  • 详解MyBatis 常用写法

    详解MyBatis 常用写法

    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。这篇文章给大家介绍了MyBatis 常用写法,感兴趣的朋友跟随小编一起看看吧
    2018-11-11
  • 浅析SpringBoot2底层注解@Conditional@ImportResource

    浅析SpringBoot2底层注解@Conditional@ImportResource

    这篇文章主要为大家介绍了SpringBoot2底层注解@Conditional@ImportResource的分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05

最新评论