11

I am trying to use openfire REST-API-Client. I am calling method to add user to the openfire using following code.

AuthenticationToken authenticationToken = new AuthenticationToken("username","password");

RestApiClient restApiClient = new RestApiClient("url",port, authenticationToken);

UserEntity openFireUser = restApiClient.getUser(user.getUsername());

When I call the api I get following exception.

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=text/html;charset=UTF-8, type=class org.igniterealtime.restclient.entity.UserEntity, genericType=class org.igniterealtime.restclient.entity.UserEntity.
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:231)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1085)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:808)
    at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326)
    at org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:115)

I googled and it looks there is some problem with the dependencies. But nothing worked.

Below is my build.gradle

compile(group: 'org.igniterealtime', name :'rest-api-client', version: igniterealtime_rest_api_version){
        exclude group: 'org.slf4j', module: 'slf4j-simple'
        exclude group: 'org.slf4j', module: 'slf4j-api'
    }

I also, tried adding following dependencies to my build.gradle, but it did not work.

compile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: '2.23'
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: '2.2'
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-moxy', version: '2.24'
compile group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-json-provider', version: '2.4.1'
ajm
  • 12,863
  • 58
  • 163
  • 234
  • 4
    Do you connect to the correct URL? In the error message it says that the response you received has media type `text/html` which, obviously, cannot be parsed into a user entity. This most likely happens either due to not receiving a successful response (200 OK) or due to connecting to the wrong URL. – Christoph Böhme Aug 04 '17 at 05:49
  • Do some debugging. Check the status code and body. Checking the status code before deserializing on the client side is always a good idea, so you can do something else on an error status – Paul Samsotha Aug 04 '17 at 06:05
  • Got the issue. Actually I had to install the REST API plugin in openfire. – ajm Aug 04 '17 at 06:07
  • @ashishjmeshram - facing same issue, in java code for a rest call - both request, response specify the content-type as application/json but getting exception as `org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=text/html;charset=UTF-8, type=interface java.util.Map, genericType=interface java.util.Map.` Could you please explain how did you fix your issue? – mjs Nov 06 '18 at 17:34
  • @ChristophBöhme, thanks! In my case it was caused by a WRONG endpoint address! I was revolving around the error until i checked another service that was working fine (and with an invalid address it caused the same error). – marcolopes Jan 21 '20 at 06:48

3 Answers3

2

issue is occurring because mismatch of media type text/html to entity. you can using restful service with media type text/html media type but you need to use media type Application/json. and also check the requested url and media type of request and response.

also use

@Produces("application/json")
@Consumes(MediaType.APPLICATION_JSON)

and make response with proper status code and Mediatype

Anshul Sharma
  • 3,432
  • 1
  • 12
  • 17
2

Let's first look at how Jersey JAX-RS will parse a JSON response with a correct Content-Type: application/json. When it gets such a response, it looks for any available implementation of the javax.ws.rs.ext.MessageBodyReader interface which is annotated as:

@Consumes(MediaType.APPLICATION_JSON)

This can be any implementation, but for our example we added MOXyJsonProvider as a dependency to the project:

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-moxy</artifactId>
    <version>${jersey.version}</version>
</dependency>

Next, we want to make it also handle Content-Type: text/plain responses. For this, we inherit our custom response reader from MOXyJsonProvider at the same time annotating it with MediaType.TEXT_PLAIN:

@Provider
@Consumes(MediaType.TEXT_PLAIN)
public class MyCustomResponseReader extends MOXyJsonProvider {

    @Override
    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return genericType.equals(MyCustomClass.class);
    }

    @Override
    public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
            InputStream entityStream) throws IOException, WebApplicationException {
        return super.readFrom(type, genericType, annotations, mediaType, httpHeaders, entityStream);
    }

}

Note that in the overridden readFrom() method all we do is just call super.readFrom() of the parent class MOXyJsonProvider.

Finally, we need to register our custom reader in the instance of javax.ws.rs.client.Client that will be querying our web service:

Client client = ClientBuilder.newBuilder().build().register(MyCustomResponseReader.class);

Now a text/plain response will be parsed like any application/json one.

GitHub

Full solution can be found on GitHub: PlainTextResponseReader

Credits

I based this solution on the information found in the following resources:

Stack Overflow

Other

Denis Abakumov
  • 355
  • 3
  • 11
  • you are reading in text from a request to convert to an obect for your back end. the name "MyCustomResponseReader" , should be "MyCustomRequestReader" – Jeryl Cook Mar 06 '20 at 13:07
  • @JerylCook: This is an example for the client. It sends a request to the server and converts its response into an entity. Hence the response reader. In order for MyCustomRequestReader to make sense this should be a server app. – Denis Abakumov Apr 24 '20 at 15:57
0

Had the same issue. The bean was simply missing a default constructor.