简体   繁体   中英

Error while deserializing array JSON with Jackson

hope someone can help. I'm trying to deserialize an array of JSON of the class Product fetched from the webservice of Prestashop 1.7 using and url like this http://myshop.com/api/products/?display=full&filter[reference]=[0003]&output_format=JSON . The JSON output is like that

{
"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"
    }
]

}

The class Products is just a List of the class Product define like this:

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

And the class Product like this:

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
}

There are more fields but I omit then because it doesn't matter.

I know how to deserialize the class Product but how can I get the List<Product> from the JSON? I'm using jackson-databind-2.9.8.jar .

Thanks in advance and have a nice weekend. EDITED: When I try to do this:

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

I get this error

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$1.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$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.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)

Even when all the fields are marked with @JsonProperty or @JsonIgnore like this one

@JsonIgnore
private LanguageElements deliveryInStock;

You can use any of the below approach to allow deserialization if your input JSON has extra fields:

  1. You can configure entire ObjectMapper to not fail on extra fields:

    ObjectMapper mapper = new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

     Products products = mapper.readValue(url, Products.class); 
  2. Annotate your Product class with @JsonIgnoreProperties(ignoreUnknown = true)

I think you may understand this, but at a basic level, you are doing it wrong.

The name of the fields in the class must exactly match the names of the fields in the JSON or you must use the @JsonProperty annotation to identify the exact field name in the JSON. Here is an example showing how to map the new field from the JSON to your object:

public class Product
{
  @JsonProperty("new")
  private String _new;
}

Notice that the name in the @JsonProperty annotation exactly matches the field name in the JSON. As long as that holds true, the actual name of the JAVA field does not matter. This would also work for the "new" field:

public class Product
{
  @JsonProperty("new")
  private String thisFieldNameDoesNotMatter;
}

Edit: Additional details added to reflect the edit to the question.

The answer to your problem is this: Pay Attention.

Actually read the error that Jackson gave you:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: 
Unrecognized field "delivery_in_stock"
... additional details included by Jackson, but deleted here.

The Jackson error message identifies that there is an unrecognized field in the JSON named "delivery_in_stock".

Either add a field to contain the "delivery_in_stock" field value from the JSON or instruct Jackson to ignore unmapped properties using this annotation:

@JsonIgnoreProperties(ignoreUnknown = true)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM