Decoder

RestClient会自动根据用户的 Headers 与 期望Entity类型 等选择合适的Decoder进行解码。RestClient内置了下面这些Decoder

  • Json

    • jackson :默认,自动通过SPI的方式注入到RestClient中

    • fastjson :需要引入fastjson依赖,并将FastJsonCodec添加到RestClient中

    • gson :需要引入gson依赖,并将GsonCodec添加到RestClient中

  • ProtoBuf :需要引入ProtoBuf依赖,并将ProtoBufCodec添加到RestClient中

  • String :自动通过SPI的方式注入到RestClient中

  • byte[] :自动通过SPI的方式注入到RestClient中

除此之外RestClient也支持用户自定义解码器。

使用Json Decoder

当Response的contentTypeMediaType.APPLICATION_JSON,将自动使用Json Decoder来来进行Decode

final RestClient client = RestClient.ofDefault();
RestResponseBase response  = client.get("localhost:8080/aaa")
        .execute()
        .toCompletableFuture()
        .get();

//当 response.contentType() == MediaType.APPLICATION_JSON 时将自动使用Json Decoder
Person person = response.bodyToEntity(Person.class);

使用ProtoBuf Decoder

Step1 : 引入ProtoBuf依赖

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
</dependency>

Step2 : 使用 ProtoBuf Decoder 进行解码

将ProtoBufCodec加入到RestClient中, 当Response的contentTypeProtoBufCodec.PROTO_BUF,且response.bodyToEntity()传入的类型为com.google.protobuf.Message的子类时,将自动使用ProtoBuf Decoder来进行Decode

//将ProtoBufCodec加入到RestClient中
final RestClient client = RestClient.create()
        .addDecoder(new ProtoBufCodec())
        .build();

RestResponseBase response = client.get("localhost:8080/aaa")
        .execute()
        .toCompletableFuture()
        .get();

//当 ProtoBufCodec.PROTO_BUF.isCompatibleWith(response.contentType()),且 Person 为 Message 的子类时,将自动使用ProtoBuf Decoder
Person person = response.bodyToEntity(Person.class);

使用String Encoder

response.bodyToEntity()传入的类型为String.class,且Response的contentType不为MediaType.APPLICATION_JSON时,将自动使用String Decoder来进行Decode

final RestClient client = RestClient.ofDefault();
RestResponseBase response = client.get("localhost:8080/aaa")
        .execute()
        .toCompletableFuture()
        .get();

//当 !MediaType.APPLICATION_JSON.isCompatibleWith(response.contentType()) 时,自动使用String Decoder来进行Decode
String result = response.bodyToEntity(String.class);

使用byte[] Encoder

response.bodyToEntity()传入的类型为byte[].class,且Response的contentType不为MediaType.APPLICATION_JSON时,将自动使用byte[] Decoder来进行Decode

final RestClient client = RestClient.ofDefault();
RestResponseBase response = client.get("localhost:8080/aaa")
        .execute()
        .toCompletableFuture()
        .get();

//当 !MediaType.APPLICATION_JSON.isCompatibleWith(response.contentType()) 时,自动使用byte[] Decoder来进行Decode
byte[] result = response.bodyToEntity(byte[].class);

自定义Decoder

RestClient内置的Decoder无法满足用户需求时,用户可以自定义Decoder,示例如下:

public class StringDecoder implements ByteDecoder {

    @Override
    public Object doDecode(DecodeContext<byte[]> ctx) {
        if (String.class.isAssignableFrom(ctx.targetType())) {
            return new String(ctx.content().value());
        }
        return ctx.next();
    }
}

配置Decoder

Builder

在构造RestClient时传入自定义的Decoder实例,如:

final RestClient client = RestClient.create()
        .addDecoder(ctx -> {
            //decode...
            return ctx.next();
        })
        .build();

SPI

普通SPI

RestClient支持通过SPI的方式加载Decoder接口的实现类,使用时只需要按照SPI的加载规则将自定义的Decoder放入指定的目录下即可。

DecoderFactory

如果用户自定义的Decoder对于不同RestClient的配置有不同的实现,则用户可以实现DecoderFactory接口,并按照SPI的加载规则将自定义的DecoderFactory放入指定的目录下即可。

public interface DecoderFactory {
    Collection<Decoder> decoders(RestClientOptions clientOptions);
}

RestClient构建时将调用DecoderFactory.decoders(RestClientOptions clientOptions),该方法返回的所有Decoder都将加入到构建好的RestClient中。

直接绑定Request

Decoder可以直接绑定Request,使用方式如下:

final RestResponseBase response = client.post(url)
        .entity(new File("aaa"))
        .decoder(ctx -> {
            //decode...
            return ctx.next();
        })
        .execute()
        .toCompletableFuture()
        .get();

执行时机

请求处理完整流程中的Decoder

DecodeAdvice

用户可以通过DecodeAdviceDecode前后进行来插入业务逻辑,来对要解码的 ResponseContent 或者 Decode后的对象 进行修改替换等操作。

示例

public class DecodeAdviceImpl implements DecodeAdvice {
    @Override
    public Object aroundDecode(DecodeAdviceContext ctx) throws Exception {
        //...before decode
        Object decoded = ctx.next();
        //...after decode
        return decoded;
    }
}

配置方式

Builder

在构造RestClient时传入自定义的DecodeAdvice实例,如:

final RestClient client = RestClient.create()
        .addDecodeAdvice(ctx ->{
            //...before decode
            Object decoded = ctx.next();
            //...after decode
            return decoded;
        })
        .build();

SPI

普通SPI

RestClient支持通过SPI的方式加载DecodeAdvice接口的实现类,使用时只需要按照SPI的加载规则将自定义的DecodeAdvice放入指定的目录下即可。

DecodeAdviceFactory

如果用户自定义的DecodeAdvice对于不同RestClient的配置有不同的实现,则用户可以实现DecodeAdviceFactory接口,并按照SPI的加载规则将自定义的DecodeAdviceFactory放入指定的目录下即可。

public interface DecodeAdviceFactory {
    Collection<DecodeAdvice> decodeAdvices(RestClientOptions clientOptions);
}

RestClient构建时将调用DecodeAdviceFactory.decodeAdvices(RestClientOptions clientOptions),该方法返回的所有DecodeAdvice都将加入到构建好的RestClient中。

执行时机

请求处理完整流程中的DecodeAdvice


Last modified April 22, 2022: add docs about traffic-split (34b84ce)