0

I have JSON paylaod as below:

{
  "status": "ok",
  "result": {
    "result": [
      {
        "product_id": "1420-131617-82",
        "sku": "1420-131617",
        "display_sku": "8DD 355 100-411",
        "genart_number": 82,
        "name": "Bremsscheibe",
        "description": null,
        "additional_info_text": null,
        "product_url": "https://www.autoteile5000.de/product/1420-131617-82",
        "image_url": "https://static.autoteile5000.de/product-images/HLP/4625-462502682-3-255-1548045462267.jpg",
        "brand": "HELLA PAGID",
        "eans": [
          "4082300365078"
        ],
        "manufacturer_product_number": "8DD 355 100-411",
        "data_supplier_number": "4625",
        "pricehammer": false,
        "buyable": true,
        "bulky_good": false,
        "risky_good": false,
        "hazardous_good": false,
        "car_specific": true,
        "has_deposit": false,
        "is_exchange_part": false,
        "visibility_status": "active",
        "deleted": false
      }
    ]
  }
}

This is method how I deserialise it:

public List<SimpleProductDto> getProducts(ProductForm productForm) {

    JsonParser jsonParser = new JsonParser();
    try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("data/product/2210-0929-818/product.json") ) {
        String text = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name());
        //System.out.println("print text : " + text);
        //Read JSON file
        JsonObject objectFromString = jsonParser.parse(text).getAsJsonObject();
       // System.out.println(objectFromString.toString());

        JsonObject objectFromString1 = objectFromString.getAsJsonObject("result");
       // System.out.println(objectFromString.toString());

       // System.out.println(objectFromString1.toString());

        JsonArray jsonArray = objectFromString1.getAsJsonArray("result");
        System.out.println("printing json array : " +jsonArray.toString());

        ObjectMapper oMapper = new ObjectMapper();
        for(JsonElement element : jsonArray){
            JsonObject productObj = element.getAsJsonObject();
            System.out.println("printing json object : " + productObj.toString());
            SimpleproductDtoMapper productDtoList = oMapper.readValue(productObj.toString(), SimpleproductDtoMapper.class);
        }
      // List<SimpleproductDtoMapper> productDtoList = oMapper.readValue(jsonArray.toString(), new TypeReference<List<SimpleproductDtoMapper>>() {});

       // Map<String, SimpleproductDtoMapper> items = productDtoList.stream().collect(Collectors.toMap(SimpleproductDtoMapper::getProductId, Function.identity()));

        //items.forEach((k, v) -> System.out.println("Item : " + k + " Count : " + v));

        //Iterate over employee array
        //productList.forEach(emp -> parseProductObject((JSONObject) emp));

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

This is my POJO:

public class SimpleproductDtoMapper {

@SerializedName("product_id")
private String productId;
private String sku;
@SerializedName("display_sku")
private String displaySku;
@SerializedName("genart_number")
private Integer genartNumber;
private String name;
private String description;
@SerializedName("additional_info_text")
private String additionalInfoText;
@SerializedName("product_url")
private String productUrl;
@SerializedName("image_url")
private String imageUrl;
private String brand;
private List<String> eans;
@SerializedName("manufacturer_product_number")
private String manufacturerProductNumber;
@SerializedName("data_supplier_number")
private String dataSupplierNumber;
private boolean pricehammer;
private boolean buyable;
@SerializedName("bulky_good")
private boolean bulkyGood;
@SerializedName("risky_good")
private boolean riskyGood;
@SerializedName("hazardous_good")
private boolean hazardousGood;
@SerializedName("car_specific")
private boolean carSpecific;
@SerializedName("has_deposit")
private boolean hasDeposit;
@SerializedName("is_exchange_part")
private boolean isExchangePart;
@SerializedName("visibility_status")
private VisibilityStatusDto visibilityStatus;
@SerializedName("deleted")
private boolean deleted;
}

I get the folllowing exception:

at [Source: (String)"{"product_id":"1420-131617-82","sku":"1420-131617","display_sku":"8DD 355 100-411","genart_number":82,"name":"Bremsscheibe","description":null,"additional_info_text":null,"product_url":"https://www.autoteile5000.de/product/1420-131617-82","image_url":"https://static.autoteile5000.de/product-images/HLP/4625-462502682-3-255-1548045462267.jpg","brand":"HELLA PAGID","eans":["4082300365078"],"manufacturer_product_number":"8DD 355 100-411","data_supplier_number":"4625","pricehammer":false,"buyable":tr"[truncated 174 chars]; line: 1, column: 16] (through reference chain: com.kfz24.mockingservice.mapper.SimpleproductDtoMapper["product_id"]) 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.ObjectMapper._readMapAndClose(ObjectMapper.java:4013) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004) at com.kfz24.mockingservice.service.impl.MockingProductServiceImpl.getProducts(MockingProductServiceImpl.java:49) at com.kfz24.mockingservice.controller.MockingProductController.getProducts(MockingProductController.java:29)

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
Vinaya Nayak
  • 1,083
  • 3
  • 16
  • 29

2 Answers2

2

Because @SerializedName is from Gson but not Jackson .The equivalent in Jackson is @JsonProperty.

So change all @SerializedName to @JsonProperty. Also , Jackson by default only deserialize the public fields if it does not marked with @JsonProperty.

So for you , I suggest that the simplest way is to make sure all fields are marked with @JsonProperty (e.g. name, brand etc.)

Ken Chan
  • 84,777
  • 26
  • 143
  • 172
1

Using jsonschema2pojo you can generate POJO class with Jackson annotations. Choose Jackson 2.x to generate model with Jackson annotations. Source type should be JSON. Below you can see Product class I have generated using this tool. all properties are public, so change them to private and generate getters and setters.

class Product {

    @JsonProperty("product_id")
    public String productId;
    @JsonProperty("sku")
    public String sku;
    @JsonProperty("display_sku")
    public String displaySku;
    @JsonProperty("genart_number")
    public Integer genartNumber;
    @JsonProperty("name")
    public String name;
    @JsonProperty("description")
    public Object description;
    @JsonProperty("additional_info_text")
    public Object additionalInfoText;
    @JsonProperty("product_url")
    public String productUrl;
    @JsonProperty("image_url")
    public String imageUrl;
    @JsonProperty("brand")
    public String brand;
    @JsonProperty("eans")
    public List<String> eans = null;
    @JsonProperty("manufacturer_product_number")
    public String manufacturerProductNumber;
    @JsonProperty("data_supplier_number")
    public String dataSupplierNumber;
    @JsonProperty("pricehammer")
    public Boolean pricehammer;
    @JsonProperty("buyable")
    public Boolean buyable;
    @JsonProperty("bulky_good")
    public Boolean bulkyGood;
    @JsonProperty("risky_good")
    public Boolean riskyGood;
    @JsonProperty("hazardous_good")
    public Boolean hazardousGood;
    @JsonProperty("car_specific")
    public Boolean carSpecific;
    @JsonProperty("has_deposit")
    public Boolean hasDeposit;
    @JsonProperty("is_exchange_part")
    public Boolean isExchangePart;
    @JsonProperty("visibility_status")
    public String visibilityStatus;
    @JsonProperty("deleted")
    public Boolean deleted;

    @Override
    public String toString() {
        return "Product{" +
                "productId='" + productId + '\'' +
                ", sku='" + sku + '\'' +
                ", displaySku='" + displaySku + '\'' +
                ", genartNumber=" + genartNumber +
                ", name='" + name + '\'' +
                ", description=" + description +
                ", additionalInfoText=" + additionalInfoText +
                ", productUrl='" + productUrl + '\'' +
                ", imageUrl='" + imageUrl + '\'' +
                ", brand='" + brand + '\'' +
                ", eans=" + eans +
                ", manufacturerProductNumber='" + manufacturerProductNumber + '\'' +
                ", dataSupplierNumber='" + dataSupplierNumber + '\'' +
                ", pricehammer=" + pricehammer +
                ", buyable=" + buyable +
                ", bulkyGood=" + bulkyGood +
                ", riskyGood=" + riskyGood +
                ", hazardousGood=" + hazardousGood +
                ", carSpecific=" + carSpecific +
                ", hasDeposit=" + hasDeposit +
                ", isExchangePart=" + isExchangePart +
                ", visibilityStatus='" + visibilityStatus + '\'' +
                ", deleted=" + deleted +
                '}';
    }
}

I noticed you wanted to skip result(Object) -> result(Array) levels. See how to do that with Jackson:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.CollectionType;

import java.io.File;
import java.io.FileInputStream;
import java.util.List;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);

        JsonNode jsonNode = mapper
                .reader()
                .at("/result/result")
                .readTree(new FileInputStream(jsonFile));

        CollectionType productsType = mapper.getTypeFactory().constructCollectionType(List.class, Product.class);
        List<Product> products = mapper.convertValue(jsonNode, productsType);
        System.out.println(products);
    }
}

Above code prints:

[Product{productId='1420-131617-82', sku='1420-131617', displaySku='8DD 355 100-411', genartNumber=82, name='Bremsscheibe', description=null, additionalInfoText=null, productUrl='https://www.autoteile5000.de/product/1420-131617-82', imageUrl='https://static.autoteile5000.de/product-images/HLP/4625-462502682-3-255-1548045462267.jpg', brand='HELLA PAGID', eans=[4082300365078], manufacturerProductNumber='8DD 355 100-411', dataSupplierNumber='4625', pricehammer=false, buyable=true, bulkyGood=false, riskyGood=false, hazardousGood=false, carSpecific=true, hasDeposit=false, isExchangePart=false, visibilityStatus='active', deleted=false}]
Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
  • Thanks for your reply .. but private VisibilityStatusDto visibilityStatus is an object and @JsonProperty("visibility_status") doesn't work for Object ? – Vinaya Nayak Feb 28 '19 at 09:37
  • @VinayaNayak, in your `JSON` payload `"visibility_status": "active"` is a `string` not `object`. Does this `JSON` is correct? If yes, update your model. – Michał Ziober Feb 28 '19 at 09:42
  • `public enum VisibilityStatusDto { ACTIVE(1), INACTIVE(2); private Integer id; private VisibilityStatusDto(Integer id) { this.id = id; } public Integer getId() { return this.id; } }` Its an Enum but json payload from other service is sending it as string. How can I map this string to enum type in mu model? – Vinaya Nayak Feb 28 '19 at 09:46
  • Take a look on this [question](https://stackoverflow.com/questions/12468764/jackson-enum-serializing-and-deserializer). Let me know what is the result. – Michał Ziober Feb 28 '19 at 10:05
  • Also take a look on this [question](https://stackoverflow.com/questions/31689107/deserializing-an-enum-with-jackson/31689416). It looks like you need to annotate your `enum`. – Michał Ziober Feb 28 '19 at 12:28
  • 1
    Thanks for the help!! – Vinaya Nayak Mar 01 '19 at 09:50
  • @VinayaNayak, I'm glad I could help. Please take a look on: [How does accepting an answer work?](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – Michał Ziober Mar 01 '19 at 10:08