How JSON parses immutable object in Java + Jersey
So, I just tried Jersey for REST services and it looks like we're doing great. I only expose get services, and all the object types I expose with these services have an immutable object representation in Java. By default Jersey seems to use a parser (JAXB?), Requiring @XmlRootElement annotation for the class to be parsed, null-argument constructors and setters.
I am using Gson with no null argument constructor, no setters, and final on all fields without any problem. Is there a way to do this from Jersey (i.e. Used by paser)? I've seen solutions with adapter classes that map data from an immutable object to a mutable view, but this seems like a lot of boilerplate (new classes, more annotations, etc.) if it can be achieved with Gson without any additions.
Note. 1) I've heard people promoting the use of the zero-arg constructor and arguing that Gson shouldn't work without it. This is not what interests me. 2) I actually tried google search, but my keywords might be off. In other words, humiliate me in moderation.
EDIT 1: My webservice is working if I like it:
@XmlRootElement
public class Code{
private String code; //Silly object just used for example.
public Code(){}
//(G || S)etters
}
With this class, exposing an object:
@GET
@Produces(MediaType.APPLICATION_JSON)
public Set<Code> get(@QueryParam("name") String name) { // Here I want to use a class of my own instead of String name, haven't figured out how yet.
return this.codeService.get(name);
}
If I replace the code with the following, the webservice stops working:
public class Code{
private final String code;
@JsonCreator
public Code(@JsonProperty("code") String code) {
this.code = code;
}
//Getters omitted
}
I want to be able to: 1) have immutable objects that can be parsed to / from json and 2) be able to define something like @RequestBody in Spring MVC for my incoming objects.
source to share
This can actually be pretty easy with Genson . You just need a jar and then configure the Genson function to use constructors with arguments (if you don't want to annotate it).
Genson genson = new GensonBuilder().useConstructorWithArguments(true).create();
// and then register it with jersey
new ResourceConfig().register(new GensonJaxRSFeature().use(genson));
Or you can use JsonProperty for arguments. For details, see the User Guide .
source to share