【问题标题】:Force spring RestTemplate to process plain text as JSON?强制spring RestTemplate 将纯文本处理为JSON?
【发布时间】:2018-09-03 07:52:53
【问题描述】:

Web API 正在响应带有 Content-Type:text/plain; charset=utf-8 的请求,但消息的格式就像是 JSON,例如。

{
"total": 168,
"page": 0,
"pageCount": 1,
...
}

在 Spring 中,此消息使用 RestTemplate 进行处理,并将 JSON 自动映射到 ModelDto POJO,

restTemplate.getForObject(url, ModelDto::class.java) 

这会产生以下错误:

org.springframework.web.client.RestClientException:无法提取响应:没有找到适合响应类型 [class api.ModelDto] 和内容类型 [text/plain;charset=utf-8] 的 HttpMessageConverter

尽管 Content-Type 是纯文本,但有什么方法可以让 spring 将此消息视为 JSON 并对其进行解析?

【问题讨论】:

    标签: java json spring rest


    【解决方案1】:

    更新

    无需创建自定义HttpMessageConverter,因为AbstractHttpMessageConverter 有一个方法setSupportedMediaTypes,可用于更改支持的媒体类型:

    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON));
    restTemplate.getMessageConverters().add(0, converter);
    

    我认为可以通过实现自己的HttpMessageConverter<T>

    RestTemplate 使用它将原始响应转换为某种表示形式(例如,POJO)。由于它有一个转换器列表,它可以根据其类型(例如application/json 等)找到特定响应的特定转换器。

    因此,HttpMessageConverter<T> 的实现应该类似于默认的 MappingJackson2HttpMessageConverter,但支持的媒体类型已更改:

    public class MappingJackson2HttpMessageConverter2 extends AbstractJackson2HttpMessageConverter {
    
        private String jsonPrefix;
    
        public MappingJackson2HttpMessageConverter2() {
            this(Jackson2ObjectMapperBuilder.json().build());
        }
    
        public MappingJackson2HttpMessageConverter2(ObjectMapper objectMapper) {
            // here changed media type
            super(objectMapper, MediaType.TEXT_PLAIN);
        }
    
        public void setJsonPrefix(String jsonPrefix) {
            this.jsonPrefix = jsonPrefix;
        }
    
        public void setPrefixJson(boolean prefixJson) {
            this.jsonPrefix = (prefixJson ? ")]}', " : null);
        }
    
    
        @Override
        protected void writePrefix(JsonGenerator generator, Object object) throws IOException {
            if (this.jsonPrefix != null) {
                generator.writeRaw(this.jsonPrefix);
            }
            String jsonpFunction =
                    (object instanceof MappingJacksonValue ? ((MappingJacksonValue) object).getJsonpFunction() : null);
            if (jsonpFunction != null) {
                generator.writeRaw("/**/");
                generator.writeRaw(jsonpFunction + "(");
            }
        }
    
        @Override
        protected void writeSuffix(JsonGenerator generator, Object object) throws IOException {
            String jsonpFunction =
                    (object instanceof MappingJacksonValue ? ((MappingJacksonValue) object).getJsonpFunction() : null);
            if (jsonpFunction != null) {
                generator.writeRaw(");");
            }
        }
    
    }
    

    然后你可以把这个添加到RestTemplate对象:

    restTemplate.getMessageConverters().add(0, new MappingJackson2HttpMessageConverter2());
    

    【讨论】:

    • 谢谢,让我试试,然后会回复
    • 看起来另一种方法是只更改入站标头。 stackoverflow.com/questions/42592440/…
    • 更新了我的答案
    • @MykolaYashchenko MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setSupportedMediaTypes(Arrays.asList(TEXT_PLAIN, MediaType.APPLICATION_JSON)); restTemplate.getMessageConverters().add(0, converter); 我在转换器中添加了 TEXT_PLAIN 仍然面临同样的问题。 [class com.fasterxml.jackson.databind.JsonNode] and content type [text/plain;charset=ISO-8859-1];
    • @NagendraNigade 我猜原因是“text/plain;charset=ISO-8859-1”与“text/plain”不同
    猜你喜欢
    • 1970-01-01
    • 2012-10-13
    • 2016-10-31
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    相关资源
    最近更新 更多