简体   繁体   中英

How to correctly map a JSON structure to an object?

How to correctly map the following structure to an object There is JSON:

{"store": [{
      "id":"100",
      "products": {
         "prod1":["price","quantity"],   //Maximum 2 elements
         "prod2":["price","quantity"],   //Maximum 2 elements
         "prod3":["price","quantity"]    //Maximum 2 elements
         //There may be many (known or not..prod4, prod5....)
        }}]}

Classes:

@Data
@NoArgsConstructor
public class Store {

    @JsonProperty("store")
    private Set<Stores> stores;
}

@Data
@NoArgsConstructor
public class Stores {

    @JsonProperty("id")
    private int id;

    @JsonProperty("products")
    private Set<Products> productsSet;
}    

@Data
@NoArgsConstructor
public class Products {
    ??????
}

How do I need to write in class Products?

Mapper:

//omit exceptions and other code
public Store toStoreFromJson(String str) {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.readValue(str, Store.class);

}

The main problem is that your products are dynamic, and can be any number of them. So you are not dealing with a collection (Set or List), but more with a dictionary, like a Map.

This solution might not be the desired (will need an adapter to desired model):

class Stores {

    @JsonProperty("id")
    private int id;

    @JsonProperty("products")
    private Products productsSet;
}

@Getter
@Setter
class Products extends LinkedHashMap<String, String[]> {
}

And the test:

   Store store = mapper.readValue("{\"store\": ....", Store.class);

    assertEquals(1, store.stores.size());

    Products product = store.getStores().stream().map(Stores::getProductsSet).findFirst().orElseThrow();
    product.forEach((name, prices) -> {
        System.out.println(name + ": " + Arrays.toString(prices));
    });

Will print:

prod1: [price, quantity]
prod2: [price, quantity]
prod3: [price, quantity]

======================================================================

Better approach would be to use a collection to represent products:

{
  "store": [
    {
      "id": "100",
      "products": [
        {"name": "prod1", "prices": ["price","quantity"]},
        {"name": "prod2", "prices": ["price","quantity"]},
        {"name": "prod3", "prices": ["price","quantity"]}
      ]
    }
  ]
}

The only downside of this approach would be the possibility of duplicates. But it depends if you can change the JSON structure.

It worked

@Data
@NoArgsConstructor
public class Stores {

    @JsonProperty("id")
    private int id;

    @JsonProperty("products")
    private Map<String, T> productsSet;
}    

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