使用 Jackson 反序列化数组 JSON 时出错
Error while deserializing array JSON with Jackson
希望有人能提供帮助。我正在尝试反序列化从 Prestashop 1.7 的 Web 服务获取的 class Product
的 JSON 数组,使用 url 像这样 http://myshop.com/api/products/?display=full&filter[reference]=[0003]&output_format=JSON
。
JSON 输出就是这样
{
"products": [{
"id": 1,
"id_manufacturer": "0",
"id_supplier": "0",
"id_category_default": "2",
"new": null,
"cache_default_attribute": "0",
"id_default_image": "",
"id_default_combination": 0,
"id_tax_rules_group": "3",
"position_in_category": "0",
"manufacturer_name": false,
"quantity": "0"
},
{
"id": 2,
"id_manufacturer": "0",
"id_supplier": "0",
"id_category_default": "2",
"new": null,
"cache_default_attribute": "0",
"id_default_image": "",
"id_default_combination": 0,
"id_tax_rules_group": "3",
"position_in_category": "0",
"manufacturer_name": false,
"quantity": "0"
}
]
}
class Products
只是 class 的 List
Product
定义如下:
public class Products {
private List <Product> products;
public Products() {
super();
}
public List<Product> getProducts(){
return this.products;
}
public void setProducts(List<Product> products){
this.products = products;
}
}
而 class Product
是这样的:
public class Product(){
@JsonProperty("id")
private long id;
@JsonProperty("id_manufacturer")
private long idManufacturer;
@JsonProperty("id_supplier")
private long idSupplier;
@JsonProperty("id_category_default")
private long idCategoryDefault;
@JsonProperty("new")
private String _new;
@JsonProperty("cache_default_attribute")
private long cacheDefaultAttribute;
@JsonProperty("id_default_image")
private long idDefaultImage;
@JsonProperty("id_default_combination")
private long idDefaultCombination;
@JsonProperty("id_tax_rules_group")
private long idTaxRulesGroup;
@JsonProperty("position_in_category")
private long positionInCategory;
@JsonProperty("manufacturer_name")
private String manufacturerName;
@JsonProperty("quantity")
private long quantity;
//getters and setters
}
还有更多字段,但我省略了,因为这并不重要。
我知道如何反序列化 class Product
但如何从 JSON 中获取 List<Product>
?
我正在使用 jackson-databind-2.9.8.jar
.
提前致谢,祝周末愉快。
编辑:
当我尝试这样做时:
SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(df);
URL url = new URL("http://myshop.com/api/products/?display=full&filter[reference]=[0003]&output_format=JSON");
Products products = mapper.readValue(url, Products.class);
我收到这个错误
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "delivery_in_stock" (class com.fnieves.precios.pshop4j.pojos.entities.Product), not marked as ignorable (58 known properties: "active", "show_price", "low_stock_alert", "advanced_stock_management", "quantity", "date_add", "state", "visibility", "uploadable_files", "low_stock_threshold", "supplier_reference", "id", "id_shop_default", "new", "cache_default_attribute", "id_category_default", "additional_shipping_cost", "height", "upc", "pack_stock_type", "id_default_combination", "location", "id_default_image", "type", "customizable", "redirect_type", "position_in_category", "depth", "width", "wholesale_price", "price", "reference", "cache_has_attachments", "cache_is_pack", "additional_delivery_times", "show_condition", "unit_price_ratio", "available_for_order", "available_date", "minimal_quantity", "id_supplier", "indexed", "ean13", "id_manufacturer", "isbn", "weight", "ecotax", "id_type_redirected", "id_tax_rules_group", "text_fields", "online_only", "condition", "on_sale", "manufacturer_name", "quantity_discount", "is_virtual", "unity", "date_upd"])
at [Source: (URL); line: 1, column: 628] (through reference chain: com.fnieves.precios.pshop4j.pojos.list.Products["products"]->java.util.ArrayList[0]->com.fnieves.precios.pshop4j.pojos.entities.Product["delivery_in_stock"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:823)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1153)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1589)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1567)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:294)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:286)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2959)
at TestJson.readArray(TestJson.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=15=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
即使所有字段都标有 @JsonProperty
或 @JsonIgnore
像这样
@JsonIgnore
private LanguageElements deliveryInStock;
我想你可能理解这一点,但在基本层面上,你做错了。
class 中的字段名称必须与 JSON 中的字段名称完全匹配,或者您必须使用 @JsonProperty
注释来标识中的确切字段名称JSON。
这是一个示例,显示如何将 JSON 中的 new
字段映射到您的对象:
public class Product
{
@JsonProperty("new")
private String _new;
}
注意 @JsonProperty
注释中的名称与 JSON 中的字段名称完全匹配。
只要那是真的,
JAVA 字段的实际名称无关紧要。
这也适用于 "new" 字段:
public class Product
{
@JsonProperty("new")
private String thisFieldNameDoesNotMatter;
}
编辑:添加了其他详细信息以反映对问题的编辑。
你的问题的答案是:注意。
实际阅读杰克逊给你的错误:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "delivery_in_stock"
... additional details included by Jackson, but deleted here.
Jackson 错误消息表明存在无法识别的
JSON 中名为 "delivery_in_stock" 的字段。
添加一个字段以包含 JSON 中的 "delivery_in_stock" 字段值,或者使用此注释指示 Jackson 忽略未映射的属性:
@JsonIgnoreProperties(ignoreUnknown = true)
如果您的输入 JSON 有额外字段,您可以使用以下任何方法允许反序列化:
您可以将整个 ObjectMapper 配置为不会在额外字段上失败:
ObjectMapper 映射器 = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Products products = mapper.readValue(url, Products.class);
使用@JsonIgnoreProperties(ignoreUnknown = true)
注释您的产品class
希望有人能提供帮助。我正在尝试反序列化从 Prestashop 1.7 的 Web 服务获取的 class Product
的 JSON 数组,使用 url 像这样 http://myshop.com/api/products/?display=full&filter[reference]=[0003]&output_format=JSON
。
JSON 输出就是这样
{
"products": [{
"id": 1,
"id_manufacturer": "0",
"id_supplier": "0",
"id_category_default": "2",
"new": null,
"cache_default_attribute": "0",
"id_default_image": "",
"id_default_combination": 0,
"id_tax_rules_group": "3",
"position_in_category": "0",
"manufacturer_name": false,
"quantity": "0"
},
{
"id": 2,
"id_manufacturer": "0",
"id_supplier": "0",
"id_category_default": "2",
"new": null,
"cache_default_attribute": "0",
"id_default_image": "",
"id_default_combination": 0,
"id_tax_rules_group": "3",
"position_in_category": "0",
"manufacturer_name": false,
"quantity": "0"
}
]
}
class Products
只是 class 的 List
Product
定义如下:
public class Products {
private List <Product> products;
public Products() {
super();
}
public List<Product> getProducts(){
return this.products;
}
public void setProducts(List<Product> products){
this.products = products;
}
}
而 class Product
是这样的:
public class Product(){
@JsonProperty("id")
private long id;
@JsonProperty("id_manufacturer")
private long idManufacturer;
@JsonProperty("id_supplier")
private long idSupplier;
@JsonProperty("id_category_default")
private long idCategoryDefault;
@JsonProperty("new")
private String _new;
@JsonProperty("cache_default_attribute")
private long cacheDefaultAttribute;
@JsonProperty("id_default_image")
private long idDefaultImage;
@JsonProperty("id_default_combination")
private long idDefaultCombination;
@JsonProperty("id_tax_rules_group")
private long idTaxRulesGroup;
@JsonProperty("position_in_category")
private long positionInCategory;
@JsonProperty("manufacturer_name")
private String manufacturerName;
@JsonProperty("quantity")
private long quantity;
//getters and setters
}
还有更多字段,但我省略了,因为这并不重要。
我知道如何反序列化 class Product
但如何从 JSON 中获取 List<Product>
?
我正在使用 jackson-databind-2.9.8.jar
.
提前致谢,祝周末愉快。 编辑: 当我尝试这样做时:
SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(df);
URL url = new URL("http://myshop.com/api/products/?display=full&filter[reference]=[0003]&output_format=JSON");
Products products = mapper.readValue(url, Products.class);
我收到这个错误
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "delivery_in_stock" (class com.fnieves.precios.pshop4j.pojos.entities.Product), not marked as ignorable (58 known properties: "active", "show_price", "low_stock_alert", "advanced_stock_management", "quantity", "date_add", "state", "visibility", "uploadable_files", "low_stock_threshold", "supplier_reference", "id", "id_shop_default", "new", "cache_default_attribute", "id_category_default", "additional_shipping_cost", "height", "upc", "pack_stock_type", "id_default_combination", "location", "id_default_image", "type", "customizable", "redirect_type", "position_in_category", "depth", "width", "wholesale_price", "price", "reference", "cache_has_attachments", "cache_is_pack", "additional_delivery_times", "show_condition", "unit_price_ratio", "available_for_order", "available_date", "minimal_quantity", "id_supplier", "indexed", "ean13", "id_manufacturer", "isbn", "weight", "ecotax", "id_type_redirected", "id_tax_rules_group", "text_fields", "online_only", "condition", "on_sale", "manufacturer_name", "quantity_discount", "is_virtual", "unity", "date_upd"])
at [Source: (URL); line: 1, column: 628] (through reference chain: com.fnieves.precios.pshop4j.pojos.list.Products["products"]->java.util.ArrayList[0]->com.fnieves.precios.pshop4j.pojos.entities.Product["delivery_in_stock"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:823)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1153)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1589)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1567)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:294)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:286)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2959)
at TestJson.readArray(TestJson.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=15=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
即使所有字段都标有 @JsonProperty
或 @JsonIgnore
像这样
@JsonIgnore
private LanguageElements deliveryInStock;
我想你可能理解这一点,但在基本层面上,你做错了。
class 中的字段名称必须与 JSON 中的字段名称完全匹配,或者您必须使用 @JsonProperty
注释来标识中的确切字段名称JSON。
这是一个示例,显示如何将 JSON 中的 new
字段映射到您的对象:
public class Product
{
@JsonProperty("new")
private String _new;
}
注意 @JsonProperty
注释中的名称与 JSON 中的字段名称完全匹配。
只要那是真的,
JAVA 字段的实际名称无关紧要。
这也适用于 "new" 字段:
public class Product
{
@JsonProperty("new")
private String thisFieldNameDoesNotMatter;
}
编辑:添加了其他详细信息以反映对问题的编辑。
你的问题的答案是:注意。
实际阅读杰克逊给你的错误:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "delivery_in_stock"
... additional details included by Jackson, but deleted here.
Jackson 错误消息表明存在无法识别的 JSON 中名为 "delivery_in_stock" 的字段。
添加一个字段以包含 JSON 中的 "delivery_in_stock" 字段值,或者使用此注释指示 Jackson 忽略未映射的属性:
@JsonIgnoreProperties(ignoreUnknown = true)
如果您的输入 JSON 有额外字段,您可以使用以下任何方法允许反序列化:
您可以将整个 ObjectMapper 配置为不会在额外字段上失败:
ObjectMapper 映射器 = new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Products products = mapper.readValue(url, Products.class);
使用@JsonIgnoreProperties(ignoreUnknown = true)
注释您的产品class