【问题标题】:Http response Content-Type is json. Error for "Invalid mime type"Http 响应 Content-Type 为 json。 “无效的 MIME 类型”错误
【发布时间】:2019-03-29 23:41:52
【问题描述】:

我出于某种目的使用了第 3 方 API。

这个 API 用一个 URL 响应,它基本上是一个亚马逊 AWS url,它实际上包含我感兴趣的数据。

我可以通过浏览器和 Postman 调用 AWS URL,后者会返回数据。

但是通过代码,我收到以下错误:

InvalidMimeTypeException: Invalid mime type "json": does not contain '/'

我正在使用 Spring Boot 并制作 http calss,我正在使用 RestTemplate

响应头:

accept-ranges →bytes
content-length →1428
content-type →json
date →Thu, 25 Oct 2018 10:05:57 GMT
last-modified →Wed, 24 Oct 2018 18:44:44 GMT
server →AmazonS3

Content-Type 是 "json"

我用过的代码:

protected HttpHeaders httpHeader(String encodedApiKey) {
    HttpHeaders headers = new HttpHeaders();
    headers.set("Content-Type", " */*");
    headers.add(HttpHeaders.ACCEPT, " */*");
    headers.add(HttpHeaders.ACCEPT_CHARSET, StandardCharsets.UTF_8.name());

    if (encodedApiKey != null && !encodedApiKey.isEmpty()) {
      headers.add("Authorization", "Basic " + encodedApiKey);
    }
    return headers;
  }

  private HttpEntity<Tickets> getHttpEntity(String apiKey) {
    if (apiKey== null || apiKey.isEmpty()) {
      return new HttpEntity<>(httpHeader(null));
    }
    return new HttpEntity<>(httpHeader(encodeBase64(apiKey)));
  }

 ResponseEntity<Tickets> responseEntity = restTemplate.exchange(awsUri,
 HttpMethod.GET,
 httpEntity, new ParameterizedTypeReference<Tickets>() {});
}

这是一个例外:

org.springframework.http.InvalidMediaTypeException: Invalid mime type "json": does not contain '/'
    at org.springframework.http.MediaType.parseMediaType(MediaType.java:534)
    at org.springframework.http.HttpHeaders.getContentType(HttpHeaders.java:869)
    at org.springframework.web.client.HttpMessageConverterExtractor.getContentType(HttpMessageConverterExtractor.java:124)
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:88)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:959)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:942)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:689)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:662)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:339)
  1. 我做错了什么?
  2. 我尝试过使用ClientHttpRequestInterceptor,但这不会修改服务器的响应头(或Content-Type 为application/json强>)

有人知道吗?

【问题讨论】:

  • 我认为您应该在客户端的请求中使用application/json。使用邮递员发送请求的最佳方式。
  • 尝试使用此标头发送请求:headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
  • @PandeyAmit 做到了。不工作。
  • @Freemahn 不起作用。同样的问题。

标签: java spring http spring-boot resttemplate


【解决方案1】:

我没有自己检查这个案例,但它与你的案例非常相似。由于存在错误堆栈HttpMessageConverterExtractor,因此我可以假设Spring 不知道如何转换响应。所以你可以自己添加一个属性MessageConverter

protected HttpHeaders httpHeader(String encodedApiKey) {
 /***/
 restTemplate.setMessageConverters(getMessageConverters());
 ResponseEntity<Tickets> responseEntity = restTemplate.exchange(awsUri,
 HttpMethod.GET,
 httpEntity, new ParameterizedTypeReference<Tickets>() {}); 
}

private List<HttpMessageConverter<?>> getMessageConverters() {
    List<HttpMessageConverter<?>> converters = 
      new ArrayList<HttpMessageConverter<?>>();
    converters.add(new MappingJackson2HttpMessageConverter());
    return converters;
}

Here is a full explanation

UPD ResponseExctractor 示例

private class TicketsResponseExtractor extends HttpMessageConverterExtractor<Tickets> {

    public TicketsResponseExtractor (Class<Tickets> responseType,
      List<HttpMessageConverter<?>> messageConverters) {
        super(responseType, messageConverters);
    }

    @Override
    public Tickets extractData(ClientHttpResponse response) throws IOException {

        if (response.getStatusCode() == HttpStatus.OK) {
            response.getHeaders().set("Content-Type", MediaType.APPLICATION_JSON_VALUE);
            return super.extractData(response);             
        } else {
            return null;
        }
    }
}

RestTemplate 通话:

ResponseExtractor<Tickets> responseExtractor =
    new TicketsResponseExtractor(Tickets.class, restTemplate.getMessageConverters());
Tickets result =
    restTemplate.execute(awsUri, HttpMethod.GET, null, responseExtractor);

【讨论】:

  • 我已经尝试过这个和拦截器。它不适合我。甚至可以修改服务器的响应标头吗? (或响应头中的特定字段)
  • 嗯。那你有没有尝试自定义ResponseExtractor
  • 我还没有。 spring 是否允许扩展/实现我们可以提供自定义 impl 的任何类?
  • 这将如何工作或解决问题?我仍然遇到同样的问题,在调试时它仍然将 content-type 提供为“json”
  • MessageConverter 实际上并未将响应的标头字段转换为 Content-Type。我错过了什么吗?
猜你喜欢
  • 2017-01-24
  • 1970-01-01
  • 1970-01-01
  • 2020-10-05
  • 1970-01-01
  • 2011-01-14
  • 2018-02-17
  • 1970-01-01
  • 2015-04-17
相关资源
最近更新 更多