How to handle the wrong JSON content type from web-services using the JAX-RS standard client API?

java, jax-rs, json, rotten-tomatoes, web-services

Solution

The answer is to use a JAX-RS ClientResponseFilter.

The request is changed to register the filter:

public MovieSearchResults search(String query) {
    return client
        .register(JsonContentTypeResponseFilter.class)
        .target("http://api.rottentomatoes.com/api/public/v1.0/movies.json")
        .queryParam("apikey", API_KEY)
        .queryParam("q", query)
        .request(MediaType.APPLICATION_JSON)
        .get(MovieSearchResults.class);
}

The filter itself simply replaces the content-type header:

public class JsonContentTypeResponseFilter implements ClientResponseFilter {

    @Override
    public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
        List<String> contentType = new ArrayList<>(1);
        contentType.add(MediaType.APPLICATION_JSON);
        responseContext.getHeaders().put("Content-Type", contentType);
    }
}

Problem

I want to use the Rotten Tomatoes API to search for movies. I have an equivalent fully working application that uses TMDB rather than Rotten Tomatoes. I use the standard JAX-RS Client, provided by JBoss RESTEasy with the RESTEasy Jackson2 provider (I can't post my API key of course): ``` public MovieSearchResults search(String query) { return client .target("http://api.rottentomatoes.com/api/public/v1.0/movies.json") .queryParam("apikey", API_KEY) .queryParam("q", query) .request(MediaType.APPLICATION_JSON) .get(MovieSearchResults.class); } ``` The MovieSearchResults class is simply a JAXB annotated class to bind the JSON. The immediate problem is that the Rotten Tomatoes API is returning a response with a content-type of "text/javascript" for all of its JSON responses. They've shown a reluctance to change their services even though this is clearly the wrong content-type to set when returning JSON, so right now it is what it is. The exception I get when I invoke the service is: ``` Exception in thread "main" javax.ws.rs.client.ResponseProcessingException: javax.ws.rs.ProcessingException: Unable to find a MessageBodyReader of content-type text/javascript;charset=ISO-8859-1 and type class MovieSearchResults ``` So the question is: is there a simple way to get/configure the standard JAX-RS Client to recognise the returned "text/javascript" content-type as "application/json"? These questions are similar, but the accepted answers appear to use JBoss-specific API and I'd like to do it only via the JAX-RS Client API.

Original source

Related problems