Java Jersey:找不到适合类型 [简单类型,类事物] 的构造函数:无法从 JSON 对象实例化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31094354/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 10:37:58  来源:igfitidea点击:

Jersey: No suitable constructor found for type [simple type, class Thing]: can not instantiate from JSON object

javajerseyHymansonjersey-2.0

提问by Eduardo

I have a resource with a method like:

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

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

Thing:

事物:

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

When I make a PUT request like:

当我发出 PUT 请求时:

PUT /rest/add HTTP/1.1
Host: localhost:8135
Content-Type: application/json
Cache-Control: no-cache

{"symbol":"some symbol","name":"some name"}

I get the following response:

我收到以下回复:

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?)

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

Why is Jersey/Hymanson not deserializing my JSON object into my POJO?

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

采纳答案by Paul Samsotha

You need a no-arg constructor and setters, or use @JsonCreator. Easiest thing to do would be just to add the no-arg with setters. Hymanson needs the setters when deserializing. For serialization, all that's needed are getters.

您需要一个无参数的构造函数和 setter,或者使用@JsonCreator. 最简单的方法就是添加带有 setter 的 no-arg。Hymanson 在反序列化时需要 setter。对于序列化,所需要的只是 getter。

EDIT

编辑

To keep it immutable, you can use @JsonCreatoron the constructor. For example

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

@JsonCreator
public Thing(@JsonProperty("symbol") String symbol, 
             @JsonProperty("name") String name) {

    this.symbol = symbol;
    this.name = name;
}

See more Hymanson Annotations: @JsonCreator demystified

查看更多Hymanson 注释:@JsonCreator 揭秘

回答by OrigamiMarie

I'm not absolutely positive, but I think this is it.

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

The way that Hymanson wants to work is this: it creates the object using the default (no argument) constructor. Then it uses setters to set each of the instance variables. This may seem like the long way around, but it's really the only way, because Hymanson can't really be smart enough to figure out what order to pass the constructor parameters in. So your code has two main issues (well, three, but I'm going to assume that your class was called Stock before you mostly cleaned it up for posting ;-) ).
1. You need a no-argument constructor. From what I know, java provides a default constructor if you don't write one, but as soon as you make any constructor, the default no-argument constructor goes away.
2. You need setters for your instance variables (and making them public isn't good enough, they have to have actual setters). Oh it looks like your instance variables are final, that's not going to work. My favorite way to manage all the copy/pasted setters is to use a library called lombok. Anyway, for now you just need those setters.

Hymanson 想要工作的方式是这样的:它使用默认(无参数)构造函数创建对象。然后它使用 setter 来设置每个实例变量。这可能看起来很长,但它确实是唯一的方法,因为 Hymanson 真的不够聪明,无法弄清楚传递构造函数参数的顺序。所以你的代码有两个主要问题(好吧,三个,但是我将假设你的课程在你大部分清理它以发布之前被称为 Stock ;-))。
1. 你需要一个无参数的构造函数。据我所知,如果您不编写,java 会提供一个默认构造函数,但是一旦您创建任何构造函数,默认的无参数构造函数就会消失。
2. 你需要为你的实例变量设置 setter(让它们公开是不够的,他们必须有实际的 setter)。哦,看起来你的实例变量是最终的,那是行不通的。我最喜欢的管理所有复制/粘贴设置器的方法是使用一个名为 lombok 的库。不管怎样,现在你只需要那些二传手。