Jersey:找不到类型的合适构造函数:无法从JSON对象实例化

我有一个资源,其方法如下:

@PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("/add") public Response putThing(Thing thing) { try { //Do something with Thing object return Response.status(HttpStatus.SC_OK).build(); } catch (Exception e) { log.error("Request failed", e); return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).build(); } } 

事情:

 public class Thing { private final String symbol; private final String name; public Stock(String symbol, String name) { this.symbol = symbol; this.name = name; } public String getSymbol() { return this.symbol; } public String getName() { return this.name; } } 

当我发出PUT请求时:

 PUT /rest/add HTTP/1.1 Host: localhost:8135 Content-Type: application/json Cache-Control: no-cache {"symbol":"some symbol","name":"some name"} 

我收到以下回复:

找不到类型[simple type,class Thing]的合适构造函数:无法从JSON对象实例化(缺少默认构造函数或创建者,或者可能需要添加/启用类型信息?)

为什么Jersey / Jackson没有将我的JSON对象反序列化为我的POJO?

你需要一个no-arg构造函数和setter,或者使用@JsonCreator 。 最容易做的事情就是添加带有setter的no-arg。 在反序列化时jackson需要安装者。 对于序列化,所需的只是getter。

编辑

为了使其不可变,您可以在构造函数上使用@JsonCreator 。 例如

 @JsonCreator public Thing(@JsonProperty("symbol") String symbol, @JsonProperty("name") String name) { this.symbol = symbol; this.name = name; } 

查看更多Jackson Annotations:@JsonCreator揭秘

我不是绝对积极的,但我认为就是这样。

Jackson希望工作的方式是:它使用默认(无参数)构造函数创建对象。 然后它使用setter来设置每个实例变量。 这似乎是漫长的过程,但它确实是唯一的方法,因为jackson真的不够聪明,无法弄清楚传递构造函数参数的顺序。所以你的代码有两个主要问题(好吧,三个,但是我会假设你的class级被称为股票,然后你大部分时间将其清理过来发布;-))。
1.你需要一个无参数的构造函数。 据我所知,java提供了一个默认构造函数,如果你不编写一个,但只要你创建任何构造函数,默认的无参数构造函数就会消失。
2.你需要实例变量的setter(并将它们公开为不够好,它们必须有实际的setter)。 哦,看起来你的实例变量是最终的,这是行不通的。 我最喜欢管理所有复制/粘贴的setter的方法是使用一个名为lombok的库。 无论如何,现在你只需要那些制定者。