Reputation: 1487
The following code uses the Jersey2 client (v 2.22.2) with the built-in Moxy JSON support. I am trying to marshal a generified wrapper class into JSON. As you can see below the json
property isn't unmarshalling as intended.
When I change the type for the json
property to Service
and 'ungenerify' the class everything works as intended but I would prefer to be able to do this with generics so I don't have to create a bunch of these wrapper classes for each type that needs to be wrapped in this fashion.
JSONWrapper.java
public class JSONWrapper<T> implements Serializable {
private T json;
public T getJson() { return this.json; }
public void setJson (T payload) { this.json = payload; }
public JSONWrapper() {}
}
Service.java
public class Service implements Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
MyClient.java
public class MyClient {
private Client jerseyClient;
public void createService(Service item) {
Invocation.Builder invocationBuilder = buildRequest(SERVICE_PATH);
JSONWrapper<Service> wrapper = new JSONWrapper<>();
wrapper.setJson(item);
final Response response = invocationBuilder.post(Entity.entity(wrapper, MediaType.APPLICATION_JSON_TYPE));
}
public MyClient() {
this.jerseryClient = ClientBuilder.newBuilder().build();
}
public static void main(String[] args) {
MyClient myClient = new MyClient();
Service myService = new Service();
myService.setName("foo");
myClient.createService(myService);
}
}
With the logging filter turned on I am seeing that Moxy's marshalling of things looks like so:
{"json":"com.baz.Service@5674e1f2"}
When I want it to look like so
{"json":"{"name": "foo"}"}
Upvotes: 1
Views: 394
Reputation: 209052
Because of type erasure, the generic type is wiped out at runtime, so MOXy doesn't know the generic type and just spits out its toString
. This is one of the limitations of using MOXy (it relies on some JAXB functionality). To get around this, JAX-RS has the GenericEntity
that let's us wrap the generic type, so it's known to serializers.
JsonWrapper<Service> service = new JsonWrapper<>();
user.setJson(new Service("blah"));
GenericEntity<JsonWrapper<Service>> entity
= new GenericEntity<JsonWrapper<Service>>(service){};
Response response = target("test").request().post(Entity.json(entity));
From what I just tested with MOXy, for some reason it spits out an extra "type":"service"
property in the JSON. I am not completely sure why. I haven't used MOXy in a while. I've had too many problems with it. Personally, I'd recommend switching over to Jackson. With Jackson you will not have this type problem. You could get away with not using GenericEntity
, and it will work out the box. If you're using Maven, just add the following dependency and remove MOXy
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey2.version}</version>
</dependency>
If you're not using Maven, have a look at this post.
Upvotes: 1