当前位置: 首页 > 知识库问答 >
问题:

Spring reactive WebClient获得内容类型为“text/plain;charset=utf-8”的json响应

谈禄
2023-03-14

我在使用Spring5 reactive WebClient时遇到了一个问题,当时我请求一个endpoint,该endpoint返回一个格式正确的json响应,内容类型为“text/plain;charset=utf-8”。例外情况是

org.springframework.web.reactive.function.UnsupportedMediaTypeException:
Content type 'text/plain;charset=UTF-8' not supported for bodyType=MyDTOClass

以下是我提出请求的方式:

webClient.get().uri(endpoint).retrieve().bodyToFlux(MyDTOClass.class)

编辑:头是“正确”设置的(Accept,Content-Type),我尝试了不同的Content-Type(json,json+UTF8,text plain,text plain+UTF8)约束,但没有成功。我认为问题是.bodyToFlux(MyDToClass.Class)不知道如何将“文本”转换为MyDToClass对象。如果我将请求更改为:

webClient.get().uri(endpoint).retrieve().bodyToFlux(String.class)

我能读懂琴弦。

编辑2:下一段引用摘自Spring文档(https://docs.Spring.io/Spring/docs/current/spring-framework-reference/web-reactive.html#webflux-codecs-jackson)

默认情况下,Jackson2EncoderJackson2Decoder都不支持String类型的元素。相反,默认的假设是字符串或字符串序列表示序列化的JSON内容,由CharSequenceEncoder呈现。如果您需要的是从flux 呈现一个JSON数组,请使用flux#collectToList()并编码一个mono >

我认为解决方案是定义一个新的解码器/读取器,以便将字符串转换为MyDTOClass,但我不知道如何做到这一点。

共有1个答案

华浩壤
2023-03-14

万一有人需要,下面是解决方法:

这个答案(https://stackoverflow.com/A/57046640/13333357)是关键。我们必须添加一个自定义解码器,以便指定什么和如何反序列化响应。

但是我们必须记住这一点:类级别的anotation@jsonIgnoreProperties默认设置为json映射器,对其他映射器不起作用。因此,如果您的DTO不匹配所有响应“JSON”属性,反序列化将失败。

...
WebClient.builder()
        .baseUrl(url)
        .exchangeStrategies(ExchangeStrategies.builder().codecs(configurer ->{
                ObjectMapper mapper = new ObjectMapper();
                mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                configurer.customCodecs().decoder(new Jackson2JsonDecoder(mapper, MimeTypeUtils.parseMimeType(MediaType.TEXT_PLAIN_VALUE)));
                }).build())
        .build();
...
 类似资料: