java Jersey:找不到适合类型[simple type,class Thing]的构造函数:无法从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"}
我得到以下回应:
No suitable constructor found for type [simple type, class Thing]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
为什么Jersey/Jackson没有将我的JSON对象反序列化到我的POJO中
# 1 楼答案
我不是绝对肯定,但我想就是这样
Jackson希望的工作方式是:它使用默认(无参数)构造函数创建对象。然后它使用setter来设置每个实例变量。这似乎有很长的路要走,但这确实是唯一的办法,因为Jackson不可能真的足够聪明,弄清楚传递构造函数参数的顺序。因此,您的代码有两个主要问题(好吧,三个问题,但我假设您的类在您主要清理它以便发布之前被称为Stock;-)
1.你需要一个无参数构造函数。据我所知,如果不编写构造函数,java会提供一个默认构造函数,但一旦创建了任何构造函数,默认的无参数构造函数就会消失
2.你的实例变量需要设置器(公开它们还不够好,它们必须有实际的设置器)。看起来你的实例变量是最终的,这是行不通的。我最喜欢的管理所有复制/粘贴设置器的方法是使用名为lombok的库。不管怎样,现在你只需要那些二传手
# 2 楼答案
您需要一个无参数构造函数和setter,或者使用
@JsonCreator
。最简单的方法就是用setters添加no arg。杰克逊在反序列化时需要二传手。对于序列化,只需要getter编辑
为了保持它不变,可以在构造函数上使用
@JsonCreator
。比如查看更多Jackson Annotations: @JsonCreator demystified