Jersey:找不到适合类型[简单类型、Thing的类]的构造函数:无法从JSON对象实例化。
Jersey:找不到适合类型[简单类型、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"}
我得到以下响应:
找不到适合类型[simple type,class Thing]的构造函数:无法从JSON对象实例化(缺少默认构造函数或创建者,或者可能需要添加/启用类型信息?)
为什么Jersey / Jackson没有将我的JSON对象反序列化为我的POJO?
admin 更改状态以发布 2023年5月23日
我不是完全确定,但我认为这就是解决方案。
Jackson希望的使用方式是:使用默认(无参)构造函数创建对象,然后使用设置器设置每个实例变量。这可能看起来麻烦,但实际上它是唯一的方式,因为Jackson不能聪明到足以确定传递构造函数参数的顺序。所以您的代码有两个主要问题(好吧,三个,但我假设您的类在发布之前进行了大部分清理,名为Stock;-))。
1.您需要一个无参构造函数。据我所知,如果您不编写任何构造函数,Java提供默认构造函数,但是一旦您创建任何构造函数,默认的无参构造函数就会消失。
2.您需要实例变量的设置器(将它们设置为public不够,它们必须具有实际的设置器)。哦,看起来你的实例变量是final,那行不通。我管理所有复制/粘贴的设置器的最喜欢的方法是使用名为lombok的库。总之,现在您只需要那些设置器。
你需要一个无参数构造函数和setter,或使用@JsonCreator
。最简单的方法是添加无参数带setter的构造函数。在反序列化时,Jackson需要setter。对于序列化,只需要getter。
编辑
要保持不可变性,可以在构造函数上使用@JsonCreator
。例如
@JsonCreator public Thing(@JsonProperty("symbol") String symbol, @JsonProperty("name") String name) { this.symbol = symbol; this.name = name; }