Encoder
RestClient会自动根据用户的 Headers 与 Entity 等选择合适的Encoder进行Encode。其内置了下面这些Encoder:
-
Json
-
jackson :默认,自动通过SPI的方式注入到RestClient中
-
fastjson :需要引入
fastjson依赖,并将FastJsonCodec添加到RestClient中 -
gson :需要引入
gson依赖,并将GsonCodec添加到RestClient中
-
-
ProtoBuf :需要引入
ProtoBuf依赖,并将ProtoBufCodec添加到RestClient中 -
File :自动通过SPI的方式注入到RestClient中
-
String :自动通过SPI的方式注入到RestClient中
-
byte[] :自动通过SPI的方式注入到RestClient中
除此之外RestClient也支持用户自定义Encoder。
使用Json Encoder
指定contentType为MediaType.APPLICATION_JSON,将自动使用Json Encoder来对Entity来进行Encode。示例如下:
final RestClient client = RestClient.ofDefault();
RestResponseBase response = client.post("localhost:8080/aaa")
.contentType(MediaType.APPLICATION_JSON)
.entity(new Person("Bob","male"))
.execute()
.toCompletableFuture()
.get();
Note
其中Json相关的序列化方式默认配置了日期格式为yyyy-MM-dd HH:mm:ss
使用ProtoBuf Encoder
Step1 : 引入ProtoBuf依赖
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</dependency>
Step2 : 使用 ProtoBuf Encoder 进行编码
将ProtoBufCodec加入到RestClient中,指定contentType为ProtoBufCodec.PROTO_BUF,且Entity类型为com.google.protobuf.Message的子类时,将自动使用ProtoBuf Encoder来对Entity来进行Encode。示例如下:
//将ProtoBufCodec加入到RestClient中
final RestClient client = RestClient.create()
.addEncoder(new ProtoBufCodec())
.build();
RestResponseBase response = client.post("localhost:8080/aaa")
.contentType(ProtoBufCodec.PROTO_BUF)
.entity(message)
.execute()
.toCompletableFuture()
.get();
使用File Encoder
当Entity类型为File时,将自动使用File Encoder来对Entity来进行Encode。示例如下:
final RestClient client = RestClient.ofDefault();
RestResponseBase response = client.post("localhost:8080/aaa")
.entity(new File("tem"))
.execute()
.toCompletableFuture()
.get();
使用String Encoder
当Entity类型为String时,将自动使用String Encoder来对Entity来进行Encode。示例如下:
final RestClient client = RestClient.ofDefault();
RestResponseBase response = client.post("localhost:8080/aaa")
.entity("string")
.execute()
.toCompletableFuture()
.get();
使用byte[] Encoder
当Entity类型为byte[]时,将自动使用byte[] Encoder来对Entity来进行Encode。示例如下:
final RestClient client = RestClient.ofDefault();
RestResponseBase response = client.post("localhost:8080/aaa")
.entity("bytes".getBytes())
.execute()
.toCompletableFuture()
.get();
自定义Encoder
当RestClient内置的Encoder无法满足用户需求时,用户可以自定义Encoder,示例如下:
public class StringEncoder implements ByteEncoder {
@Override
public RequestContent<byte[]> doEncode(EncodeContext<byte[]> ctx) {
if (MediaType.TEXT_PLAIN.isCompatibleWith(ctx.contentType())) {
if (ctx.entity() != null) {
return RequestContent.of(ctx.entity().toString());
} else {
return RequestContent.of("null");
}
}
//该Encoder无法Encode这种类型,将Encode工作交给下一个Encoder
return ctx.next();
}
}
Tip
在RestClient中,同时存在多个Encoder,它们之间通过getOrder()方法返回值区分执行顺序,值越小,优先级越高。
针对当前Encoder,分为两种情况:
- 当前
Encoder可以Encode该请求: 直接返回Encode后的结果。 - 当前
Encoder不可以Encode该请求: 调用ctx.next(),将Encode工作交给下一个Encoder,如果RestClient中的所有Encoder都无法编码该请求,则RestClient将抛出CodecException异常。
配置Encoder
Builder
在构造RestClient时传入自定义的Encoder实例,如:
final RestClient client = RestClient.create()
.addEncoder(ctx -> {
//encode...
return ctx.next();
})
.build();
SPI
普通SPI
RestClient支持通过SPI的方式加载Encoder接口的实现类,使用时只需要按照SPI的加载规则将自定义的Encoder放入指定的目录下即可。
EncoderFactory
如果用户自定义的Encoder对于不同RestClient的配置有不同的实现,则用户可以实现EncoderFactory接口,并按照SPI的加载规则将自定义的EncoderFactory放入指定的目录下即可。
public interface EncoderFactory {
Collection<Encoder> encoders(RestClientOptions clientOptions);
}
在RestClient构建时将调用EncoderFactory.encoders(RestClientOptions clientOptions),该方法返回的所有Encoder都将加入到构建好的RestClient中。
直接绑定Request
Encoder可以直接绑定Request,使用方式如下:
final RestResponseBase response = client.post(url)
.entity(new File("aaa"))
.encoder(ctx -> {
//encode...
return ctx.next();
})
.execute()
.toCompletableFuture()
.get();
Tip
当Request绑定了Encoder,该Client中设置的所有Encoder将对该请求失效。即:如果当前Encoder无法Encode该请求的Entity,则RestClient将会抛出CodecException异常。
执行时机
见请求处理完整流程中的Encoder。
EncodeAdvice
用户可以通过EncodeAdvice在Encode前后插入业务逻辑,来对要Encode的 Entity 或者 Encode后的RequestContent 进行修改替换等操作。
示例
public class EncodeAdviceImpl implements EncodeAdvice {
@Override
public RequestContent<?> aroundEncode(EncodeAdviceContext ctx) throws Exception {
//...before encode
RequestContent<?> requestContent = ctx.next();
//...after encode
return requestContent;
}
}
Tip
多个EncodeAdvice之间通过getOrder()方法返回值区分执行顺序,值越小,优先级越高。
配置方式
Builder
在构造RestClient时传入自定义的EncodeAdvice实例,如:
final RestClient client = RestClient.create()
.addEncodeAdvice(ctx -> {
//...before encode
RequestContent<?> requestContent = ctx.next();
//...after encode
return requestContent;
})
.build();
SPI
普通SPI
RestClient支持通过SPI的方式加载EncodeAdvice接口的实现类,使用时只需要按照SPI的加载规则将自定义的EncodeAdvice放入指定的目录下即可。
EncodeAdviceFactory
如果用户自定义的EncodeAdvice对于不同RestClient的配置有不同的实现,则用户可以实现EncodeAdviceFactory接口,并按照SPI的加载规则将自定义的EncodeAdviceFactory放入指定的目录下即可。
public interface EncodeAdviceFactory {
Collection<EncodeAdvice> encodeAdvices(RestClientOptions clientOptions);
}
在RestClient构建时将调用EncodeAdviceFactory.encodeAdvices(RestClientOptions clientOptions),该方法返回的所有EncodeAdvice都将加入到构建好的RestClient中。
执行时机
见请求处理完整流程中的EncodeAdvice。
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.