java 如何自定义 SpringWebFlux WebClient JSON 反序列化?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43769301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to customize SpringWebFlux WebClient JSON deserialization?
提问by Martin
I'm using a spring-webflux WebClient(build 20170502.221452-172) to access a Web application producing a stream of Entryobjects (application/stream+json) like this:
我正在使用spring-webflux WebClient(构建 20170502.221452-172)来访问 Web 应用程序,该应用程序生成一个条目流(application/stream+json),如下所示:
final WebClient producerClient = WebClient.create("http://localhost:8080/");
Flux<Entry> entries = producerClient.get().uri("json-stream")
.accept(MediaType.APPLICATION_STREAM_JSON)
.exchange()
.flatMapMany(clientResponse -> clientResponse.bodyToFlux(Entry.class));
While the deserialization of the Entryobjects works fine for POJOs using standard common types including Java time (JSR-310) datatypes like java.time.Instant, I wonder what I would have to do in order to add any custom JSON to Java deserialization (e. g., a custom Hymanson ObjectMapper).
虽然Entry对象的反序列化适用于使用标准通用类型(包括 Java 时间(JSR-310)数据类型(如 java.time.Instant))的 POJO,但我想知道我必须做什么才能将任何自定义 JSON 添加到 Java 反序列化(例如,自定义 Hymanson ObjectMapper)。
I can't find any API in WebClientor in the classes of the objects produced by its builder and fluent APIs to do that.
我在WebClient或其构建器和流畅的 API 生成的对象的类中找不到任何 API来执行此操作。
Has anybody used WebClient with customized deserialization?
有没有人使用过自定义反序列化的 WebClient?
(Maybe the API is not there, yet?)
(也许 API 还不存在?)
回答by Brian Clozel
Here's an example that customizes the ObjectMapper
for JSON (de)serialization.
Note that for streaming purposes, different encoders/decoders are being used but the principle remains the same for their configuration.
这是一个自定义ObjectMapper
for JSON(反)序列化的示例。请注意,出于流传输目的,使用了不同的编码器/解码器,但其配置原理保持不变。
ExchangeStrategies strategies = ExchangeStrategies
.builder()
.codecs(clientDefaultCodecsConfigurer -> {
clientDefaultCodecsConfigurer.defaultCodecs().Hymanson2JsonEncoder(new Hymanson2JsonEncoder(new ObjectMapper(), MediaType.APPLICATION_JSON));
clientDefaultCodecsConfigurer.defaultCodecs().Hymanson2JsonDecoder(new Hymanson2JsonDecoder(new ObjectMapper(), MediaType.APPLICATION_JSON));
}).build();
WebClient webClient = WebClient.builder().exchangeStrategies(strategies).build();
回答by Ricardo
You can configure this for a specific WebClient:
您可以为特定的 WebClient 配置它:
@Autowired
public ItunesAlbumServiceImpl(ObjectMapper mapper) {
ExchangeStrategies strategies = ExchangeStrategies.builder().codecs(clientCodecConfigurer ->
clientCodecConfigurer.customCodecs().decoder(
new Hymanson2JsonDecoder(mapper,
new MimeType("text", "javascript", StandardCharsets.UTF_8)))
).build();
webClient = WebClient.builder()
.exchangeStrategies(strategies)
.baseUrl("https://itunes.apple.com")
.build();
}
But also on 'application level'
但也在“应用程序级别”
by configuring a CodecCustomizer
:
通过配置一个CodecCustomizer
:
@Bean
public CodecCustomizer HymansonLegacyJsonCustomizer(ObjectMapper mapper) {
return (configurer) -> {
MimeType textJavascript = new MimeType("text", "javascript", StandardCharsets.UTF_8);
CodecConfigurer.CustomCodecs customCodecs = configurer.customCodecs();
customCodecs.decoder(
new Hymanson2JsonDecoder(mapper, textJavascript));
customCodecs.encoder(
new Hymanson2JsonEncoder(mapper, textJavascript));
};
}
which will be made effective by the WebClientAutoConfiguration
as a WebClient.Builder
bean:
这将通过WebClientAutoConfiguration
作为WebClient.Builder
bean 来实现:
@Autowired
public ItunesAlbumServiceImpl(WebClient.Builder webclientBuilder) {
webClient = webclientBuilder.baseUrl("https://itunes.apple.com").build();
}
回答by Amit Yatagiri
with webflux 5.0.2, de-registerDefaults
使用 webflux 5.0.2,取消注册默认值
val strategies = ExchangeStrategies.builder()
.codecs { configurer ->
configurer.registerDefaults(false)
configurer.customCodecs().encoder(Hymanson2JsonEncoder(objectMapper, APPLICATION_JSON))
configurer.customCodecs().decoder(Hymanson2JsonDecoder(objectMapper, APPLICATION_JSON))
}.build()
回答by Sarvar Nishonboev
Configuring globally:
全局配置:
@Configuration
public class AppConfig {
private final ObjectMapper objectMapper;
@Autowired
public AppConfig(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
this.webClientBuilder = WebClient.builder()
.exchangeStrategies(exchangeStrategies());
}
private ExchangeStrategies exchangeStrategies() {
Hymanson2JsonEncoder encoder = new Hymanson2JsonEncoder(objectMapper);
Hymanson2JsonDecoder decoder = new Hymanson2JsonDecoder(objectMapper);
return ExchangeStrategies
.builder()
.codecs(configurer -> {
configurer.defaultCodecs().Hymanson2JsonEncoder(encoder);
configurer.defaultCodecs().Hymanson2JsonDecoder(decoder);
}).build();
}
}
回答by tomasulo
Since Spring 5.1.13
you can use a dedicated .codec
method to customize them:
从 Spring 开始,5.1.13
您可以使用专用.codec
方法来自定义它们:
WebClient.builder()
.codecs(configurer -> {
configurer.defaultCodecs().Hymanson2JsonEncoder(new Hymanson2JsonEncoder(new ObjectMapper(), MediaType.APPLICATION_JSON));
configurer.defaultCodecs().Hymanson2JsonDecoder(new Hymanson2JsonDecoder(new ObjectMapper(), MediaType.APPLICATION_JSON));
})
.build();