如何在Java + Jersey中解析不可变的JSON对象

4

我正在尝试使用Jersey进行REST服务,看起来一切都正常。我只公开获取服务,并且我公开的所有对象类型在Java中都有不可变的对象表示。默认情况下,Jersey似乎使用一个解析器(JAXB?),需要为应该被解析的类使用@XmlRootElement注释、零参数构造函数和setter。

我一直在使用Gson,在所有字段上没有零参数构造函数、没有setter并且使用final修饰符,一点问题都没有。是否有任何方法可以在Jersey中实现这一点(即它正在使用的解析器)?我看到过类适配器的解决方案,该适配器将数据从不可变对象映射到可变表示,但如果可以在Gson中实现而无需添加任何内容,则这似乎是很多样板文件(新类,更多注释等)。

注意:1)我听说过人们提倡使用零参数构造函数,并声称Gson不能在没有它的情况下工作。这不是我感兴趣的。2)我确实尝试了谷歌搜索,但我的关键词可能不准确。换句话说,请适度羞辱我。

编辑1: 如果我这样做,我的Web服务就可以运行:

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

使用这个类来暴露对象:

@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); 
}   

如果我用以下代码替换原始代码,Web服务将停止工作:
public class Code{
    private final String code;

    @JsonCreator
    public Code(@JsonProperty("code") String code) {
        this.code = code;
    }
    //Getters omitted
}

我希望的是能够实现以下两点内容:1)拥有不可变对象,可以将其解析为/从json解析出来;2)能够像Spring MVC中@RequestBody一样定义我传入对象的方法。

我不使用Gson,但是Jackson与@JsonCreator一起使用,可以参考这里 - Paul Samsotha
没有解决我的问题。我更新了描述,你能看到我犯的明显错误吗? - why_vincent
它有什么问题?你是否遇到了错误?如果是的话,是什么错误?还有,问题出在GET方法上吗?对于GET来说,不可变对象应该没有问题,因为只会调用对象的getter。而当框架需要创建对象时,就会出现问题,因为没有无参构造函数。 - Paul Samsotha
还要确保您添加的是实际的Jackson _JAX-RS提供程序_,而不仅仅是核心Jackson库。这取决于您使用的Jersey版本,我会指导您添加哪些依赖项。 - Paul Samsotha
我有一种感觉,这个链接会让你更好地理解一切是如何工作的,以及可能存在的问题。 - Paul Samsotha
1个回答

2

实际上,使用Genson可能非常容易。您只需要获取jar文件,然后配置Genson功能以使用带有参数的构造函数(如果您不想在其上放置注释)。

Genson genson = new GensonBuilder().useConstructorWithArguments(true).create();
// and then register it with jersey
new ResourceConfig().register(new GensonJaxRSFeature().use(genson));

或者你可以在参数上使用JsonProperty。有关详细信息,请参见用户指南


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接