Spring 引导:从服务器错误接收时如何解决 Content-Type

Spring Boot: How to resolve Content-Type when incorrectly received from server

我在 Java 中有以下 class。我期待它向 url 发出 GET 请求,取回 JSON 有效负载,并将该有效负载转换为 List<LocationData>.

package ...
import ...

@Repository
public class ProxiedLocationRepo {

    public List<LocationData> findAll() throws Exception {
        RestTemplate restTemplate = new RestTemplate();

        String url = UriComponentsBuilder
                .fromUriString("https://my-host/path")
                .queryParams("some", "queryParams")
                .toUriString();

        ResponseEntity<List<LocationData>> res = restTemplate.exchange(
                                                     url,
                                                     HttpMethod.GET,
                                                     null,
                                                     new ParameterizedTypeReference<List<LocationData>>(){});

        if (res.getStatusCode() == HttpStatus.ACCEPTED) {
            return res.getBody();
        } else {
            throw new ResponseStatusException(res.getStatusCode(), "Did not receive a 200 response from Server.");
        }
    }
}

但是,我得到了这个错误:

org.springframework.http.InvalidMediaTypeException: Invalid mime type "charset=UTF-8": does not contain '/'

这是预期的,因为如果我从 curl 执行相同的请求,并检查 headers 我得到这个(注意 Content-Type 行):

$ curl -sfi 'https://my-host/path?some=queryParams'
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 06 Mar 2019 13:58:58 GMT
Content-Type: charset=UTF-8
Content-Length: 1821
Connection: keep-alive
Vary: Accept-Encoding
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: SAMEORIGIN

... # perfectly formatted JSON payload here

我知道从该服务器返回的 Content-Type 将是 application/json,但它没有提供给我。

有没有办法告知 RestTemplate#exchange 响应的 Content-Type 是什么?如果没有,除了让服务器的所有者正确设置 Content-Type 之外,还有其他方法可以用来解决这个问题吗?

编辑: 我也尝试添加 "Accept" header 但得到了相同的结果:

$ curl -sfi 'https://my-host/path?some=queryParams' \
    -H 'Accept: application/json'

不幸的是,我认为在利用 Spring 框架时没有任何方法可以解决此问题。即使您要创建接受 ANY MIME 类型的自定义 JsonbHttpMessageConverter,Spring 仍然无法解析从请求中收到的不正确的 Content-Type(因为它找不到 "/" 在 Content-Type 字符串中)。

所以这里的解决方案是使用 java.net.HttpURLConnection 代替网络,然后使用 com.fasterxml.jackson.databind.ObjectMapper 从 JSON 映射到 POJO。

它有效,但代价是无法再利用任何 Spring 的 HTTP 处理,这可能比我单独实现的任何东西都要强大得多。