Search code examples
javaspringhttpspring-bootresttemplate

Http response Content-Type is json. Error for "Invalid mime type"


I am consuming a 3rd party API for some purpose.

This API responses with a URL, which basically is an Amazon AWS url, which actually has the data I am interested in.

I am able to call the AWS URL via browser and Postman, which responds with data.

But through code, I receive the following error:

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

I am using Spring Boot and to make http calss, I'm using RestTemplate.

Response header:

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

The Content-Type is "json"

Code I've used:

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>() {});
}

This is giving an exception:

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. What is it that I'm doing wrong ?
  2. I've tried using ClientHttpRequestInterceptor, but this won't modify the server's response header (or Content-Type to application/json)

Does anyone has any idea ?


Solution

  • I didn't check this case by my own but it is extremally similar to you case. Since in the error stack HttpMessageConverterExtractor is present I can make an assumption that Spring doesn't know how to convert a response. So you can add a propert MessageConverter by yourself:

    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 example

    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;
            }
        }
    }
    

    and RestTemplate call:

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