如何通过Spring RestTemplate更改GET请求中的响应HTTP头?

8

我有一个简单的Java Spring方法,用于创建对象

RestTemplate restTemplate = new RestTemplate();
Address address = restTemplate.getForObject(url, Address.class);

但是服务器返回给我的JSON字符串的Content-Type错误,应该是text/plain而不是application/json(在Postman中检查)。因此我会得到以下异常:

无法提取响应:没有找到适合的HttpMessageConverter用于响应类型[class Address]和内容类型[text/plain;charset=utf-8]

所以我认为,我需要更改响应头的Content-Type为正确的application/json,这样MappingJackson2HttpMessageConverter才能找到JSON字符串并正常运行代码。

3个回答

16

尝试了一个小时后,我找到了一种简短易行的方法。

默认情况下,JSON转换器仅支持"application/json"格式。我们只需要覆盖它以支持"text/plain"格式。

MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();

// support "text/plain"
converter.setSupportedMediaTypes(Arrays.asList(TEXT_PLAIN, APPLICATION_JSON));

RestTemplate template = new RestTemplate();
template.getMessageConverters().add(converter);

// It's ok now
MyResult result = tmp.postForObject("http://url:8080/api", 
            new MyRequest("param value"), MyResult.class);

2
这是如何处理崩溃的第三方集成! - Muhammad Hewedy
不确定,但在我的情况下,它在发送请求时覆盖了MediaType。因此,客户端返回不支持的MediaType错误。 - bluelurker

2

感谢您的帮助!如果我无法更改响应头,则会创建新的响应对象,并使用正确的头。

            ClientHttpRequest clientHttpRequest = new SimpleClientHttpRequestFactory().createRequest(URI.create(str), org.springframework.http.HttpMethod.GET);
            final ClientHttpResponse clientHttpResponse = clientHttpRequest.execute();
            MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
            Address address = new Address();
            //It always true, because service always returns 200 OK
            if (clientHttpResponse.getStatusCode() == HttpStatus.OK) {
                address = (Address) converter.read(address.getClass(), new HttpInputMessage() {
                    public InputStream getBody() throws IOException {
                        return clientHttpResponse.getBody();
                    }

                    public HttpHeaders getHeaders() {
                        HttpHeaders httpHeaders = new HttpHeaders();
                        httpHeaders.putAll(clientHttpResponse.getHeaders());
                        httpHeaders.put("Content-Type", Collections.singletonList(MediaType.APPLICATION_JSON_VALUE));
                        return httpHeaders;
                    }
                });
                busStop.setNearestAddress(address.toString());
            }

我相信这不是一个简单而好的解决方案,但它能够正常工作。


0

要设置请求的内容类型,您可以这样做:

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity entity = new HttpEntity(headers);
    ResponseEntity<Address> response = restTemplate.exchange(url, HttpMethod.GET,  entity, Address.class);
    Address address = response.getBody();

1
不,它不起作用。它只是更改请求头,而不是响应。 - Dmitry Torshin
您无法更改 Response 的标头,这些标头是由服务器发送的,因此,除非您编写服务器代码,否则无法实现您想要的功能。 - Orlando Vargas
请查看类似的问题:https://dev59.com/neo6XIcBkEYKwwoYJAvV - Orlando Vargas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接