将 JsonCreator 与 JsonProperty.Access.READ_ONLY 一起使用时出现 InvalidDefinitionException
Posted
技术标签:
【中文标题】将 JsonCreator 与 JsonProperty.Access.READ_ONLY 一起使用时出现 InvalidDefinitionException【英文标题】:InvalidDefinitionException while using JsonCreator with JsonProperty.Access.READ_ONLY 【发布时间】:2017-12-04 21:44:43 【问题描述】:我在尝试使用 @JsonCreator
和 @JsonProperty(value = "version", access = JsonProperty.Access.READ_ONLY)
时遇到 InvalidDefinitionException
这就是我的班级的样子:
@Entity
public class Example1 implements Serializable
private String field1;
private int field2;
private Example2 field3;
public Example1(@JsonProperty(value = "field_1", access = JsonProperty.Access.READ_WRITE) String field1,
@JsonProperty(value = "field_2", access = JsonProperty.Access.READ_ONLY) int field2,
@JsonProperty(value = "field_3_1", access = JsonProperty.Access.READ_WRITE) String field31,
@JsonProperty(value = "field_3_2", access = JsonProperty.Access.READ_WRITE) int field32
)
this.field1 = field1;
this.field2 = field2;
this.field3 = new Example2(field31, field32);
// getters and setters omitted
它抛出以下异常:
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Argument #1 of constructor [constructor for com.test.example.model.Example1, annotations: interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator
at [Source: (File); line: 1, column: 1]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:62) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:249) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:165) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:411) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:477) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4145) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3995) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2878) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
我的环境详情:
我正在使用Spring Boot 2.0.0.M2
版本和Jackson 2.9.0.pr3
。
我的意图是在反序列化期间省略 field2。
我尝试在 field2 的 setter 方法中使用@JsonIgnore
作为替代。甚至,它不适用于@JsonCreator
。
【问题讨论】:
【参考方案1】:反序列化时有两种方法可以忽略该属性
-
使用 READ_ONLY
只需为您不想反序列化的属性添加注释
@JsonProperty(access = Access.READ_ONLY)
private String readOnly;
-
使用@JsonIgnore 和@JsonProperty
这个方法要小心,你应该把@JsonIgnore放在setter之前,把@JsonProperty放在getter之前。并且对于属性应该清除没有任何注释。
@JsonProperty
public String getJsonIgnoreSetter()
return jsonIgnoreSetter;
@JsonIgnore
public void setJsonIgnoreSetter(String jsonIgnoreSetter)
this.jsonIgnoreSetter = jsonIgnoreSetter;
最后是@JsonIgnore、@JsonProperty、@JsonProperty(access = xxx)的完整注解示例。
bean的定义
public class MockBean
public MockBean()
super(MockBean.class);
public MockBean(String attr1, String ignore, String jsonIgnore, String jsonIgnoreGetter,
String jsonIgnoreSetter, String jsonIgnoreProperties, String jsonIgnorePropertiesSetter,
String jsonIgnorePropertiesGetter, String readOnly, String writeOnly)
super(MockBean.class);
this.attr1 = attr1;
this.ignore = ignore;
this.jsonIgnore = jsonIgnore;
this.jsonIgnoreGetter = jsonIgnoreGetter;
this.jsonIgnoreSetter = jsonIgnoreSetter;
this.jsonIgnoreProperties = jsonIgnoreProperties;
this.jsonIgnorePropertiesSetter = jsonIgnorePropertiesSetter;
this.jsonIgnorePropertiesGetter = jsonIgnorePropertiesGetter;
this.readOnly = readOnly;
this.writeOnly = writeOnly;
public String getAttr1()
return attr1;
public void setAttr1(String name)
this.attr1 = name;
public String getIgnore()
return ignore;
public void setIgnore(String ignore)
this.ignore = ignore;
public String getJsonIgnore()
return jsonIgnore;
public void setJsonIgnore(String jsonIgnore)
this.jsonIgnore = jsonIgnore;
@JsonIgnore
public String getJsonIgnoreGetter()
return jsonIgnoreGetter;
@JsonProperty
public void setJsonIgnoreGetter(String jsonIgnoreGetter)
this.jsonIgnoreGetter = jsonIgnoreGetter;
@JsonProperty
public String getJsonIgnoreSetter()
return jsonIgnoreSetter;
@JsonIgnore
public void setJsonIgnoreSetter(String jsonIgnoreSetter)
this.jsonIgnoreSetter = jsonIgnoreSetter;
public String getJsonIgnoreProperties()
return jsonIgnoreProperties;
public void setJsonIgnoreProperties(String jsonIgnoreProperties)
this.jsonIgnoreProperties = jsonIgnoreProperties;
public String getJsonIgnorePropertiesSetter()
return jsonIgnorePropertiesSetter;
@JsonIgnoreProperties
public void setJsonIgnorePropertiesSetter(String jsonIgnorePropertiesSetter)
this.jsonIgnorePropertiesSetter = jsonIgnorePropertiesSetter;
@JsonIgnoreProperties
public String getJsonIgnorePropertiesGetter()
return jsonIgnorePropertiesGetter;
public void setJsonIgnorePropertiesGetter(String jsonIgnorePropertiesGetter)
this.jsonIgnorePropertiesGetter = jsonIgnorePropertiesGetter;
public String getReadOnly()
return readOnly;
public void setReadOnly(String readOnly)
this.readOnly = readOnly;
public String getWriteOnly()
return writeOnly;
public void setWriteOnly(String writeOnly)
this.writeOnly = writeOnly;
private String attr1;
@Ignore
private String ignore;
@JsonIgnore
private String jsonIgnore;
@JsonIgnore
private String jsonIgnoreGetter;
@JsonIgnore
private String jsonIgnoreSetter;
@JsonIgnoreProperties
private String jsonIgnoreProperties;
private String jsonIgnorePropertiesSetter;
private String jsonIgnorePropertiesGetter;
@JsonProperty(access = Access.READ_ONLY)
private String readOnly;
@JsonProperty(access = Access.WRITE_ONLY)
private String writeOnly;
测试 JSON
"name": "name",
"description": "description",
"attr1":"attr1",
"ignore": "ignore",
"jsonIgnore": "jsonIgnore",
"jsonIgnoreGetter": "jsonIgnoreGetter",
"jsonIgnoreSetter": "jsonIgnoreSetter",
"jsonIgnoreProperties": "jsonIgnoreProperties",
"jsonIgnorePropertiesSetter": "jsonIgnorePropertiesSetter",
"jsonIgnorePropertiesGetter": "jsonIgnorePropertiesGetter",
"readOnly": "readOnly",
"writeOnly": "writeOnly"
反序列化结果:如果值为null,则不反序列化。
【讨论】:
以上是关于将 JsonCreator 与 JsonProperty.Access.READ_ONLY 一起使用时出现 InvalidDefinitionException的主要内容,如果未能解决你的问题,请参考以下文章
Jackson 还需要 getter 方法来使用 @JsonCreator 正确序列化 bean 属性
为啥构造函数用@JsonCreator注解时,它的参数必须用@JsonProperty注解?
@JsonCreator 不适用于 Spring MVC 中的 @RequestParams
在顶级地图上使用@JacksonInject和@JsonCreator