This discussion is archived
7 Replies Latest reply: May 7, 2013 10:00 PM by r035198x RSS

JAXB Based JSON support not working with Jersey JAX-RS

873896 Newbie
Currently Being Moderated
Do I make something wrong using JAXB based JSON support with the Jersey 1.17 Client API?
The code below delivers
415
[text/html;charset=utf-8]
Mai 01, 2013 8:23:30 AM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: A message body reader for Java class client.Pair, and Java type class client.Pair, and MIME media type text/html; charset=utf-8 was not found
Mai 01, 2013 8:23:30 AM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: The registered message body readers compatible with the MIME media type are:
*/* ->
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
com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy

Exception in thread "main" com.sun.jersey.api.client.ClientHandlerException: A message body reader for Java class client.Pair, and Java type class client.Pair, and MIME media type text/html; charset=utf-8 was not found
     at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:561)
     at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:517)
     at client.ComputeConcat.main(ComputeConcat.java:39)



package server;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
*
* calling with data as JSON serialization
* $ curl -X POST --data-binary "{ \"first\":\"Hello, \", \"second\":\"World.\" }" \
* -H "Content-Type: application/json" -H "Accept: application/json" \
* --user exampleuser:changeit \
* http://localhost:8080/JAXRSServer/rs/concatEngine/concat
* delivers
* { "first":"Hello, World." }
*/
@Path("/concatEngine")
public class ConcatEngine {
@POST
@Path("/concat")
// MediaType.APPLICATION_XML,
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Pair concat(Pair data) {
Pair res = new Pair();
res.setFirst(data.getFirst() + data.getSecond());
return res;
}
}



package server;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class Pair {
protected String first;
protected String second;

public Pair() {
}

public String getFirst() {
return first;
}

public void setFirst(String first) {
this.first = first;
}

public String getSecond() {
return second;
}

public void setSecond(String second) {
this.second = second;
}
}



package client;

import javax.ws.rs.core.MediaType;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;

public class ComputeConcat {

private static WebResource getHttpResource() {
ClientConfig config = new DefaultClientConfig();
// config.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
// config.getClasses().add(JSONRootElementProvider.class);
Client client = Client.create(config);
return client.resource(
"http://localhost:8080/JAXRSServer/rs/concatEngine/concat");
}


public static void main(String[] args) {
Pair pair = new Pair();
pair.setFirst("Hello, "); pair.setSecond("World!");

WebResource resource = getHttpResource();

// resource.accept(MediaType.APPLICATION_XML);
resource.accept(MediaType.APPLICATION_JSON);
resource.type(MediaType.APPLICATION_JSON);
// resource.header("content-type", MediaType.APPLICATION_JSON);

ClientResponse response = resource.post(ClientResponse.class, pair);
System.out.println(response.getStatus());
System.out.println(response.getHeaders().get("Content-Type"));
Pair res = response.getEntity(Pair.class);
System.out.println(res.getFirst());
}

}


My web.xml (under Tomcat) if that should be of interest:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

<display-name>JAXRSServer</display-name>

<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>
com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>server</param-value>
</init-param>
<!-- init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rs/*</url-pattern>
</servlet-mapping>
</web-app>



If changing @Consumes({MediaType.APPLICATION_JSON}) to @Consumes({MediaType.APPLICATION_XML}) for the concat method, then the code operates. However, the input pair is sent as XML and not as JSON serialization. It seems like the Jersy Client does not automatically serialize the pair object to JSON but only to XML, although imho it should.

Any ideas? Thank you!
  • 1. Re: JAXB Based JSON support not working with Jersey JAX-RS
    gimbal2 Guru
    Currently Being Moderated
    The error seems really off to me.
    A message body reader for Java class client.Pair, and Java type class client.Pair, and MIME media type text/html; charset=utf-8
    Jersey seems to be either expecting or getting HTML content as a response. I'm wondering if the JAX-RS service you are invoking is actually doing what you are thinking it should be doing.
  • 2. Re: JAXB Based JSON support not working with Jersey JAX-RS
    873896 Newbie
    Currently Being Moderated
    Jersey seems to be either expecting or getting HTML content as a response. I'm wondering if
    the JAX-RS service you are invoking is actually doing what you are thinking it should be doing
    Please note that the first 2 lines are output of my client programm. The http error code is 415. That means that only the error message is text/html. If only using MediaType.APPLICATION_XML on the various occurences instead of ...JSON the program works perfect! Also in its current form using curl as indicated in the comment of the server class, it works with JSON perfectly.

    The problem is imho the client of Jersey, which does not perfomr the right (JSON) serialization.
  • 3. Re: JAXB Based JSON support not working with Jersey JAX-RS
    gimbal2 Guru
    Currently Being Moderated
    de-serialization since the crash seems to happen in getEntity(). The post request you send seems to work just fine, so the serialization part must work.

    I have no clue what could be wrong. If you get no other responses I would try the jersey user mailing list:

    https://java.net/projects/jersey/lists
  • 4. Re: JAXB Based JSON support not working with Jersey JAX-RS
    873896 Newbie
    Currently Being Moderated
    Posted on the user list and created an entry to the issues database of Jersey:

    https://java.net/jira/browse/JERSEY-1879

    However, I neither way I get some response. Seems that either nobody cares or that my question is somehow ridiculous. Btw. I am not the only one:

    http://stackoverflow.com/questions/12630917/posting-json-via-jersey

    The hints provided in this posting do not operate, or at least I cannot Interpret them correctly.
  • 5. Re: JAXB Based JSON support not working with Jersey JAX-RS
    873896 Newbie
    Currently Being Moderated
    I found the error:

    resource.type(MediaType.APPLICATION_JSON);
    resource.accept(MediaType.APPLICATION_JSON);
    ClientResponse response = resource.post(ClientResponse.class, pair);

    The methods of WebResource (ie post) always create new WebResource.Builder objects. That is setting the type to MediaType.APPLICATION_JSON is done in an object for the garbage collector, and not the one which issues
    post.

    The following code operates.

    WebResource resource = getHttpResource();
    WebResource.Builder builder = resource.getRequestBuilder();
    builder.accept(MediaType.APPLICATION_JSON_TYPE);
    builder.type(MediaType.APPLICATION_JSON_TYPE);
    ClientResponse response = builder.post(ClientResponse.class, pair);

    However, this behavior is poorly documented and contrintuitive. For chaining/fluent API the passed objects better should be changed and a reference to them returned.

    Hower, many thanks for your help.
  • 6. Re: JAXB Based JSON support not working with Jersey JAX-RS
    gimbal2 Guru
    Currently Being Moderated
    This strikes me as something very curious and potentially wrong. I would expect that this internally constructed builder would adopt the resource settings and apparently you have now proven this is not the case. At least not in the version of Jersey you're using. On the other hand I have not worked with the JAX-RS API long enough yet to fully understand its inner workings, perhaps I'm just making false claims.

    Nice catch by the way, and thanks for posting back a solution.
  • 7. Re: JAXB Based JSON support not working with Jersey JAX-RS
    r035198x Pro
    Currently Being Moderated
    The builder pattern is used here so you must use
    response = resource.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, pair);
    Edited by: r035198x on May 8, 2013 7:00 AM

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points