4

So I am just trying out Jersey for REST services and it seems to we working out fine. I only expose get services and all of the object types that I expose with these services have an immutable object representation in Java. By default Jersey seems to use a parser (JAXB?), requiring a @XmlRootElement annotation for the class that should be parsed, zero-arg constructor and setters.

I have been using Gson with no zero-arg constructor, no setters and final on all fields with no problems at all. Is there any way to accomplish this with Jersey(i.e. the paser it is using)? I have seen solutions with adapter classes that map data from a immutable object to a mutable representation, but this seems like a lot of boilerplate(new classes, more annotations, etc.) if it can be achieved with Gson without anything added.

Note: 1) I have heard people promote using zero-arg constructor and claim that Gson should not work without it. This is not what I am interested in. 2) I really have tried googling this but my keywords might be off. In other words, humiliate me in moderation.

EDIT 1: My webservice works if I do like this:

@XmlRootElement
public class Code{
    private String code; //Silly object just used for example.
    public Code(){}
    //(G || S)etters
}

With this class exposing the 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
}

What I want is 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.

why_vincent
  • 2,172
  • 9
  • 33
  • 49
  • I don't use Gson, but Jackson with @JsonCreator, as seen [here](http://stackoverflow.com/a/31094467/2587435), is an option. – Paul Samsotha Jul 04 '15 at 13:53
  • Didn't solve my problem. I updated the description, can you see some obvious mistake that I have made? – why_vincent Jul 06 '15 at 12:23
  • What's not working about it? Are you getting errors? If so, what? Also is the problem with the GET method.? Immutable object should be no problem with GET since only getters will be called on the object. It's with POST when the framework needs to create the object, where the no no-arg constructor becomes a problem. – Paul Samsotha Jul 06 '15 at 12:43
  • Also make sure you add the actual Jackson _JAX-RS provider_ and not just the core Jackson libraries. It depends on which Jersey version you are using, for me to point you in the direction of what dependencies to add. – Paul Samsotha Jul 06 '15 at 12:44
  • I have a feeling that [this](http://stackoverflow.com/a/30692580/2587435) will give you a better understanding of how everything works, and what may be the problem. – Paul Samsotha Jul 06 '15 at 13:19

1 Answers1

2

Actually this could be pretty easy with Genson. You just need the jar and then configure the Genson feature to use constructors with arguments (if you don't want to put annotations on 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 on the arguments. See the User Guide for more details.

eugen
  • 5,856
  • 2
  • 29
  • 26