在Jackson中,当您使用@JsonCreator
注释构造函数时,必须使用@JsonProperty
注释其参数。所以这个构造函数
public Point(double x, double y) {
this.x = x;
this.y = y;
}
成为这个:
@JsonCreator
public Point(@JsonProperty("x") double x, @JsonProperty("y") double y) {
this.x = x;
this.y = y;
}
我不明白为什么有必要。你能解释一下吗?
答案 0 :(得分:90)
Jackson必须知道将JSON对象中的字段传递给构造函数的顺序。 使用反射无法访问Java中的参数名称 - 这就是您必须在注释中重复此信息的原因。
答案 1 :(得分:41)
Java代码在运行时通常无法访问参数名称(因为它会被编译器删除),因此如果您需要该功能,则需要使用Java 8的内置功能或使用诸如ParaNamer之类的库来获取对它的访问权。
因此,为了在使用Jackson时不必使用构造函数参数的注释,您可以使用这两个Jackson模块中的任何一个:
使用 Java 8 时,此模块允许您获取无注释的构造函数参数。要使用它,首先需要注册模块:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new ParameterNamesModule());
然后使用-parameters标志编译代码:
javac -parameters ...
链接:https://github.com/FasterXML/jackson-modules-java8/tree/master/parameter-names
另一个只需要您注册模块或配置注释内省(但不是注释所指出的两者)。它允许您在1.8之前的版本的Java 上使用无注释的构造函数参数。
ObjectMapper mapper = new ObjectMapper();
// either via module
mapper.registerModule(new ParanamerModule());
// or by directly assigning annotation introspector (but not both!)
mapper.setAnnotationIntrospector(new ParanamerOnJacksonAnnotationIntrospector());
链接:https://github.com/FasterXML/jackson-modules-base/tree/master/paranamer
答案 2 :(得分:23)
可以使用jdk8避免构造函数注释,其中编译器可选地引入具有构造函数参数名称的元数据。然后使用jackson-module-parameter-names模块,Jackson可以使用此构造函数。您可以在帖子Jackson without annotations
上看到示例答案 3 :(得分:6)
因为Java字节码不保留方法或构造函数参数的名称。
答案 4 :(得分:3)
当我正确理解this时,用参数化的构造函数替换默认构造函数,因此必须描述用于调用构造函数的JSON键。
答案 5 :(得分:3)
在annotation documentation中精确定位时,注释指示参数名称用作属性名称而不进行任何修改,但可以将其指定为非空值以指定不同的名称:
答案 6 :(得分:0)
一个人可以简单地使用java.bean.ConstructorProperties注释-不再那么冗长,Jackson也接受它。例如:
import java.beans.ConstructorProperties;
@ConstructorProperties({"answer","closed","language","interface","operation"})
public DialogueOutput(String answer, boolean closed, String language, String anInterface, String operation) {
this.answer = answer;
this.closed = closed;
this.language = language;
this.anInterface = anInterface;
this.operation = operation;
}
答案 7 :(得分:0)
只要碰到它并在某个地方得到答案即可。您可以从2.7.0开始使用以下注释
class MyDict1(models.Model):
_name='my_module.my_dict1'
name=fields.Char()
child_ids=fields.One2many('my_module.my_dict2', 'parent_id')
class MyDict2(models.Model):
_name='my_module.my_dict2'
name=fields.Char()
parent_id=fields.Many2one('my_module.my_dict1')
child_ids=fields.One2many('my_module.my_dict3', 'parent_id')