首页 > 解决方案 > Getting JsonMappingException when trying to deserialize Json

问题描述

I'm getting an error when I try to map a json string to a DataProduct object:

com.fasterxml.jackson.databind.JsonMappingException: N/A (through reference chain: DataProduct["data"]->java.util.ArrayList[0])

This json string was created by being serialzed from the same DataProduct Object so I'm confused as to how this could not be working, just by looking at it, everything seems to match up

This is how I'm trying to map it:

ObjectMapper mapper = new ObjectMapper();
DataProduct dataProduct = mapper.readValue(json, DataProduct.class);

This is the json string I'm trying to map:

{ 
   "data":[ 
      { 
         "barcode":"4412312324",
         "description":"Southern Fries",
         "price":2.3,
         "onHand":0.0,
         "Aisle":"25R",
         "Location Code":"101",
         "Section":"Grocery",
         "Date_Removed":"42:53.4",
      }
   ],
   "meta":{ 
      "store":"Store 1",
      "originated":"2020-02-07T20:49:38.105629500Z",
      "correlationId":"a5ea816d-6589-4251-b951-d022a0159352"
   }
}

Here's the classes I'm trying to map to:

@Value
public class DataProduct {
  private List<Product> data;
  private DataProductMetadata meta;
}

@AllArgsConstructor
@Value
public class Product {
  @NonNull
  private String barcode;
  @NonNull
  private String description;
  @NonNull
  private Double price;
  @NonNull
  private Double onHand;

  @JsonIgnore
  @JsonUnwrapped
  private Map<String, Object> customFields;

  @JsonAnyGetter
  public Map<String, Object> getCustomFields() {
    return customFields;
  }

  @JsonAnySetter
  public void setCustomField(String name, Object value) {
    customFields.put(name, value);
  }
}

@Builder
@Value
public class DataProductMetadata {
  @NonNull
  private final String store;
  @NonNull
  private final Instant originated;
  @NonNull
  private final String correlationId;
}

标签: javajsonjackson

解决方案


I found some issues in your json and your code as well:

  1. Your json object data has a redundant ,. It causes a parsing exception.

    "Date_Removed":"42:53.4",

  2. You will get the NullPointerException in the setCustomField method because customFields hasn't been initialized yet.

  3. originated in the DataProductMetadata is not a serializable object. You can use Date instead or others which is serializable.

You can see the fixed version here

@Data
@RequiredArgsConstructor
public class DataProduct {
  private List<Product> data;
  private DataProductMetadata meta;
}

@Builder
@Data
@RequiredArgsConstructor
@NoArgsConstructor
public class DataProductMetadata {
   @NonNull
   private String store;
   @NonNull
   private Date originated;
   @NonNull
   private String correlationId;
}

@AllArgsConstructor
@RequiredArgsConstructor
@NoArgsConstructor
@Data
public class Product {
   @NonNull
   private String barcode;
   @NonNull
   private String description;
   @NonNull
   private Double price;
   @NonNull
   private Double onHand;

  @JsonIgnore
   @JsonUnwrapped
   private Map<String, Object> customFields =new HashMap<>();;

   @JsonAnyGetter
   public Map<String, Object> getCustomFields() {
      return customFields;
   }

   @JsonAnySetter
   public void setCustomField(String name, Object value) {
      customFields.put(name, value);
   }
}

Due to some lombok's annotations are used, you should add lombok library to your project but I guessed you have used this library already.


推荐阅读