简体   繁体   中英

How can I write a custom Provider class to convert JSON to Boolean?

I have an endpoint on a Webserver that returns the string literals true or false along with the Content-Type: application/json header. I'm trying to write a Jersey client that accesses this endpoint and translates the response into a simple Boolean .

The relevant part of my code looks something like this:

WebResource queryResource = client.resource("http://path.to/my/endpoint");
WebResource.Builder queryBuilder = queryResource.getRequestBuilder();
queryBuilder.addHeader("Authorization", "Bearer 1234...");
Boolean result = queryBuilder.get(new GenericType<Boolean>(){});

Unfortunately when the client tries to handle the request, I end up with a ClientHandlerException which says:

A message body reader for Java class java.lang.Boolean, and Java type class java.lang.Boolean, and MIME media type application/json; charset=UTF-8 was not found

And some more detail in the logs also highlights this:

The registered message body readers compatible with the MIME media type are:
application/json; charset=UTF-8 ->
  com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
  com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$App
  com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$App
  com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
  com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
*/* ->
  com.sun.jersey.core.impl.provider.entity.FormProvider
  com.sun.jersey.core.impl.provider.entity.StringProvider
  com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
  com.sun.jersey.core.impl.provider.entity.FileProvider
  com.sun.jersey.core.impl.provider.entity.InputStreamProvider
  com.sun.jersey.core.impl.provider.entity.DataSourceProvider
  com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
  com.sun.jersey.core.impl.provider.entity.ReaderProvider
  com.sun.jersey.core.impl.provider.entity.DocumentProvider
  com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
  com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
  com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$General
  com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
  com.sun.jersey.core.impl.provider.entity.EntityHolderReader
  com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
  com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General

My best guess is that I need to add some kind of custom @Provider class that can explicitly handle the conversion of application/json to Boolean . However I'm very new to this and have never written a Provider before. I saw some examples of people extended JacksonJsonProvider but for other uses. Can someone either show me what to do, or point me towards some resources on how I can write this Provider? (And moreover, how I add it into my Jersey client?)

You need to add MessageBodyReader for type application/json . You can easily fix this problem by adding Jersey Media Json Jackson library to your project. If you use maven add following dependency to your pom.xml :

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

EDIT

The simplest solution that do not require implementing custom MessageBodyReader or add library is read data from response manually as string and then convert it to boolean

        Client client = ClientBuilder.newClient();
        WebTarget webTarget = client.target("http://path.to/my/endpoint");
        Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
        Response response = invocationBuilder.get();
        Boolean result = Boolean.valueOf(response.readEntity(String.class));

The response is not a valid json string: ether send a if a content-type is application/json you should receive a valid json string and capture some DTO class (or javax.json.JsonObject):

eg {"flag": true}.

or you have to change the content type to text/plain.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM