Netflix Feign 编码器和解码器

在 Netflix Feign 中,使用 Feign.builder() 构建 Feign 客户端时,允许手动配置编码器和解码器,例如:

Feign.builder()
    .encoder(new Encoder.Default()) // 编码器
    .decoder(new Decoder.Default()) // 解码器
    .contract(new Contract.Default())
    .target(InterceptorFeign.class, "http://localhost:8090");

上面使用了 Netflix Feign 提供的默认编码器/解码器。下面将分别介绍编码器和解码器:

编码器(Encoder)

编码器在 Netflix Feign 中主要用于将 Java 对象转换为可以通过 HTTP 请求发送的格式,通常是将对象转换为 JSON、XML 或者其他适合网络传输的格式。例如,当你使用 Feign 客户端发送一个包含复杂对象的 POST 请求时,编码器会将这个对象序列化为合适的格式并放入请求体中。

feign.codec.Encoder 接口

feign.codec.Encoder 接口是 Netflix Feign 用于将 Java 对象编码为适合通过 HTTP 请求发送的格式的接口。它主要用于处理请求体的内容,比如将一个 Java 对象转换为 JSON、XML 或者其他格式,然后将其放入请求体中进行网络传输。

Encoder 接口只有一个 encode() 方法,签名如下:

void encode(Object object, Type bodyType, RequestTemplate template) throws IOException;

参数说明:

  • Object object:这是需要进行编码的实际 Java 对象。例如,在发送一个 POST 请求包含一个用户对象(User)时,这个 User 对象就是 object 参数。它可以是任何 Java 对象,具体取决于你的业务需求和 API 设计。

  • Type bodyType:表示 object 的类型。这个类型信息对于编码器来说非常重要,特别是在处理多态对象或者泛型类型时。例如,如果 object 是一个 List<User>,bodyType 参数就会包含 List<User>的类型信息,这有助于编码器正确地处理和序列化对象。

  • RequestTemplate template:RequestTemplate 是一个用于构建请求的模板。编码器可以使用这个模板来设置请求体。例如,在将对象编码为 JSON 格式后,可以通过 template.body(jsonString)将 JSON 字符串放入请求体中。这个模板还包含了其他请求相关的信息,如请求 URL、请求头,编码器在某些复杂场景下也可能会利用这些信息来更好地完成编码工作。

下面是 Netflix Feign 提供的默认编码器:

class Default implements Encoder {

    @Override
    public void encode(Object object, Type bodyType, RequestTemplate template) {
        if (bodyType == String.class) {
            // 如果是 String 类型
            template.body(object.toString());
        } else if (bodyType == byte[].class) {
            // 如果是字节数组
            template.body((byte[]) object, null);
        } else if (object != null) {
            // 否则抛出异常
            throw new EncodeException(format("%s is not a type supported by this encoder.", object.getClass()));
        }
    }
}

在 Netflix Feign 中,内置了 JacksonEncoder、FormEncoder、SpringFormEncoder 等编码器。

解码器(Decoder)

码器的作用与编码器相反,它用于将服务端返回的 HTTP 响应(通常是 JSON、XML 等格式)转换为 Java 对象,以便在客户端代码中方便地使用。例如,当服务端返回一个 JSON 格式的用户信息时,解码器会将这个 JSON 数据解析为一个 Java 对象(如User类的实例)。

feign.codec.Decoder 接口

feign.codec.Decoder 接口是 Netflix Feign 中用于将服务端返回的 HTTP 响应内容解码为 Java 对象的关键接口。当 Feign 客户端发送请求并收到服务端的响应后,解码器会根据响应的内容类型(如application/json、application/xml等)和目标 Java 对象类型,将响应内容转换为可以在 Java 程序中直接使用的对象。

Decoder 接口主要包含一个 decode() 方法,其签名如下:

Object decode(Response response, Type targetType) throws IOException, DecodingException;

参数说明:

  • Response response:这是从服务端接收到的完整的 HTTP 响应。它包含了响应头、响应体以及状态码等所有信息。解码器可以根据响应头中的内容类型(例如,通过检查 Content-Type 头)来确定如何正确地解码响应体。例如,如果响应头中 Content-Type 是 application/json,解码器可能会使用 JSON 解析库来处理响应体。

  • Type targetType:表示期望解码得到的 Java 对象的类型。这个类型信息对于解码器来说非常关键,它可以是一个简单的 Java 类(如 User 类),也可以是复杂的泛型类型(如 List<User>)。解码器需要根据这个目标类型来正确地将响应体内容转换为对应的 Java 对象。例如,如果目标类型是 User,解码器会尝试将响应体内容解析为一个 User 对象;如果是 List<User>,则会解析为用户对象的列表。

下面是 Netflix Feign 提供的默认解码器:

public class Default extends StringDecoder {

    @Override
    public Object decode(Response response, Type type) throws IOException {
        if (response.status() == 404 || response.status() == 204)
            return Util.emptyValueOf(type);
        if (response.body() == null)
            return null;
        if (byte[].class.equals(type)) {
            return Util.toByteArray(response.body().asInputStream());
        }
        return super.decode(response, type);
    }
    
}

在 Netflix Feign 中,内置了 JacksonDecoder、StringDecoder、StreamDecoder 等解码器。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号