Jackson:UnrecognisedPropertyException
Jackson:UnrecognisedPropertyException
我有以下 classes:
LocationCustomDataItem.java
public class LocationCustomDataItem {
private String attributeNumber;
private String attributeLabel;
private String attributeValue;
public LocationCustomDataItem() {
}
public LocationCustomDataItem(final String attributeNumber, final String attributeLabel, final String attributeValue) {
this.attributeNumber = attributeNumber;
this.attributeLabel = attributeLabel;
this.attributeValue = attributeValue;
}
/**
* @return the attributeNumber
*/
public String getAttributeNumber() {
return attributeNumber;
}
/**
* @param attributeNumber the attributeNumber to set
*/
public void setAttributeNumber(String attributeNumber) {
this.attributeNumber = attributeNumber;
}
/**
* @return the attributeLabel
*/
public String getAttributeLabel() {
return attributeLabel;
}
/**
* @param attributeLabel the attributeLabel to set
*/
public void setAttributeLabel(String attributeLabel) {
this.attributeLabel = attributeLabel;
}
/**
* @return the attributeValue
*/
public String getAttributeValue() {
return attributeValue;
}
/**
* @param attributeValue the attributeValue to set
*/
public void setAttributeValue(String attributeValue) {
this.attributeValue = attributeValue;
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, false);
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE, false);
}
LocationCustomDataAttributes.java
public class LocationCustomDataAttributes {
private final List<LocationCustomDataItem> locationCustomDataItems;
public LocationCustomDataAttributes() {
this.locationCustomDataItems = new ArrayList<>();
}
public LocationCustomDataAttributes(final List<LocationCustomDataItem> locationCustomDataItems) {
this.locationCustomDataItems = locationCustomDataItems;
}
/**
* @return unmodifiable locationCustomDataItems list
*/
public List<LocationCustomDataItem> getLocationCustomDataItems() {
return Collections.unmodifiableList(this.locationCustomDataItems);
}
/**
* Adds LocationCustoDataItem to internal collection
*
* @param item LocationCustomDataItem to add to item list
*/
public void addItem(final LocationCustomDataItem item) {
this.locationCustomDataItems.add(item);
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, false);
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE, false);
}
和这个测试 json:
{
"locationCustomDataAttributes" : {
"locationCustomDataItems" : [ {
"attributeLabel" : "testLabel1",
"attributeNumber" : "testNumber1",
"attributeValue" : "testLabel1"
}, {
"attributeLabel" : "testLabel2",
"attributeNumber" : "testNumber2",
"attributeValue" : "testLabel2"
} ]
}
}
我正在尝试使用 ObjectMapper 将 json 转换为对象,但它在 "locationCustomDataAttributes":
周围引发了无法识别的 PropertyException
MapperTest.java
@Test
public void test() throws JsonParseException, JsonMappingException, IOException {
ObjectMapper om =new ObjectMapper();
LocationCustomDataAttributes actual = om.readValue(json, LocationCustomDataAttributes.class);
LocationCustomDataAttributes expected = new LocationCustomDataAttributes();
expected.addItem(new LocationCustomDataItem("testNumber1", "testLabel1", "testValue1"));
expected.addItem(new LocationCustomDataItem("testNumber2", "testLabel2", "testValue2"));
assertThat(actual).isEqualTo(expected);
}
错误信息:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "locationCustomDataAttributes" (class com.lmig.ci.fnol.transformer.domain.LocationCustomDataAttributes), not marked as ignorable (one known property: "locationCustomDataItems"])
at [Source: {"locationCustomDataAttributes" : {"locationCustomDataItems" : [ {"attributeLabel" : "testLabel1","attributeNumber" : "testNumber1","attributeValue" : "testLabel1"},{"attributeLabel" : "testLabel2","attributeNumber" : "testNumber2","attributeValue" : "testLabel2"}]}}; line: 1, column: 36] (through reference chain: com.lmig.ci.fnol.transformer.domain.LocationCustomDataAttributes["locationCustomDataAttributes"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:62)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:833)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1096)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1467)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1445)
//等...`
我没有直接与 Jackson 合作的大量经验,所以我还没有注释 class 本身,但是从以前的努力(例如 Spring 控制器)转换无需在 class 上添加注释即可自动发生。在这种情况下,情况似乎并非如此,我从 class 中遗漏了什么,或者当前的 class 结构是否出于某种原因不适合 Jackson 自动转换?
om.readValue(json, LocationCustomDataAttributes.class)
此行要求解析 JSON 文档中的 LocationCustomDataAttributes
对象。但是 JSON 实际上包含一个包装器对象,带有 属性 可以解析为 LocationCustomDataAttributes
对象。解决方案:
为包装对象创建一个 reader。例如
ObjectReader reader = om
.readerFor(LocationCustomDataAttributes.class)
.withRootName("locationCustomDataAttributes");
LocationCustomDataAttributes actual = reader.readValue(json);
定义包装器class
class AttributesWrapper {
private LocationCustomDataAttributes locationCustomDataAttributes;
// add getters, setters, constructors etc
}
然后解析它:
LocationCustomDataAttributes actual = om
.readValue(json, AttributesWrapper.class)
.getLocationCustomDataAttributes();
我有以下 classes:
LocationCustomDataItem.java
public class LocationCustomDataItem {
private String attributeNumber;
private String attributeLabel;
private String attributeValue;
public LocationCustomDataItem() {
}
public LocationCustomDataItem(final String attributeNumber, final String attributeLabel, final String attributeValue) {
this.attributeNumber = attributeNumber;
this.attributeLabel = attributeLabel;
this.attributeValue = attributeValue;
}
/**
* @return the attributeNumber
*/
public String getAttributeNumber() {
return attributeNumber;
}
/**
* @param attributeNumber the attributeNumber to set
*/
public void setAttributeNumber(String attributeNumber) {
this.attributeNumber = attributeNumber;
}
/**
* @return the attributeLabel
*/
public String getAttributeLabel() {
return attributeLabel;
}
/**
* @param attributeLabel the attributeLabel to set
*/
public void setAttributeLabel(String attributeLabel) {
this.attributeLabel = attributeLabel;
}
/**
* @return the attributeValue
*/
public String getAttributeValue() {
return attributeValue;
}
/**
* @param attributeValue the attributeValue to set
*/
public void setAttributeValue(String attributeValue) {
this.attributeValue = attributeValue;
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, false);
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE, false);
}
LocationCustomDataAttributes.java
public class LocationCustomDataAttributes {
private final List<LocationCustomDataItem> locationCustomDataItems;
public LocationCustomDataAttributes() {
this.locationCustomDataItems = new ArrayList<>();
}
public LocationCustomDataAttributes(final List<LocationCustomDataItem> locationCustomDataItems) {
this.locationCustomDataItems = locationCustomDataItems;
}
/**
* @return unmodifiable locationCustomDataItems list
*/
public List<LocationCustomDataItem> getLocationCustomDataItems() {
return Collections.unmodifiableList(this.locationCustomDataItems);
}
/**
* Adds LocationCustoDataItem to internal collection
*
* @param item LocationCustomDataItem to add to item list
*/
public void addItem(final LocationCustomDataItem item) {
this.locationCustomDataItems.add(item);
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, false);
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE, false);
}
和这个测试 json:
{
"locationCustomDataAttributes" : {
"locationCustomDataItems" : [ {
"attributeLabel" : "testLabel1",
"attributeNumber" : "testNumber1",
"attributeValue" : "testLabel1"
}, {
"attributeLabel" : "testLabel2",
"attributeNumber" : "testNumber2",
"attributeValue" : "testLabel2"
} ]
}
}
我正在尝试使用 ObjectMapper 将 json 转换为对象,但它在 "locationCustomDataAttributes":
周围引发了无法识别的 PropertyExceptionMapperTest.java
@Test
public void test() throws JsonParseException, JsonMappingException, IOException {
ObjectMapper om =new ObjectMapper();
LocationCustomDataAttributes actual = om.readValue(json, LocationCustomDataAttributes.class);
LocationCustomDataAttributes expected = new LocationCustomDataAttributes();
expected.addItem(new LocationCustomDataItem("testNumber1", "testLabel1", "testValue1"));
expected.addItem(new LocationCustomDataItem("testNumber2", "testLabel2", "testValue2"));
assertThat(actual).isEqualTo(expected);
}
错误信息:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "locationCustomDataAttributes" (class com.lmig.ci.fnol.transformer.domain.LocationCustomDataAttributes), not marked as ignorable (one known property: "locationCustomDataItems"])
at [Source: {"locationCustomDataAttributes" : {"locationCustomDataItems" : [ {"attributeLabel" : "testLabel1","attributeNumber" : "testNumber1","attributeValue" : "testLabel1"},{"attributeLabel" : "testLabel2","attributeNumber" : "testNumber2","attributeValue" : "testLabel2"}]}}; line: 1, column: 36] (through reference chain: com.lmig.ci.fnol.transformer.domain.LocationCustomDataAttributes["locationCustomDataAttributes"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:62)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:833)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1096)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1467)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1445)
//等...`
我没有直接与 Jackson 合作的大量经验,所以我还没有注释 class 本身,但是从以前的努力(例如 Spring 控制器)转换无需在 class 上添加注释即可自动发生。在这种情况下,情况似乎并非如此,我从 class 中遗漏了什么,或者当前的 class 结构是否出于某种原因不适合 Jackson 自动转换?
om.readValue(json, LocationCustomDataAttributes.class)
此行要求解析 JSON 文档中的 LocationCustomDataAttributes
对象。但是 JSON 实际上包含一个包装器对象,带有 属性 可以解析为 LocationCustomDataAttributes
对象。解决方案:
为包装对象创建一个 reader。例如
ObjectReader reader = om .readerFor(LocationCustomDataAttributes.class) .withRootName("locationCustomDataAttributes"); LocationCustomDataAttributes actual = reader.readValue(json);
定义包装器class
class AttributesWrapper { private LocationCustomDataAttributes locationCustomDataAttributes; // add getters, setters, constructors etc }
然后解析它:
LocationCustomDataAttributes actual = om .readValue(json, AttributesWrapper.class) .getLocationCustomDataAttributes();