English 中文(简体)
Jackson custom deserializer dropped some fields inside the deserializer method
原标题:

I have a JSON object that needs to be deserialized in my use case. Also, I need to generate some fields value combining one or more attributes in the same JSON. So I chose Jackson deserialization and annotated the required fields with relevant deserialization classes like follow

@Getter
@ToString
@JsonIgnoreProperties(ignoreUnknown = true)
public class Product implements Serializable {

    @JsonProperty("item_name")
    @JsonDeserialize(using = ProductDeserializer.ItemName.class)
    private String itemName;
    
    @JsonProperty("item_code")
    @JsonDeserialize(using = CommonDeserializer.Trim.class)
    private String itemCode;
    
    @JsonProperty("demand_status")
    @JsonDeserialize(using = ProductDeserializer.DemandStatus.class)
    private boolean isDemandItem;
    
    @JsonProperty("upc")
    private long upcCode;
    
    @JsonProperty("store_condition") //multiple attributes uses, ex  store_code 
    @JsonDeserialize(using = ProductDeserializer.StoreConditionDeserializer.class)
    private StoreCondition storeCondition;

    .....

}

Deserialization class for the storeCondition variable is as follows,

public static class StoreConditionDeserializer extends JsonDeserializer<StoreCondition> {
    @Override
    public StoreCondition deserialize(JsonParser jp, DeserializationContext context) throws IOException {
        String stock_id = jp.getCodec().readValue(jp, JsonNode.class).asText();
        String store_code = jp.getCodec().readValue(jp, JsonNode.class).get("store_code").asText();
    
        /* I need to access several fields from the JSON to generate the object I need, 
           but some of them are missing here but they exist in the JSON input */
    
        //Also some logic, API calls, etc
    
        return ...;
    }
    
}

This is how my input JSON looks like

{
  "_id": 28463836,
  "item_name": "john product",
  "item_code": "doe code",
  "store_code": "T",
  "demand_status": "D",
  "upc": 874564847,
  "store_condition": "F",
  "location": "IR",
  "W_Code": "X3846"
}

If you take a look at the Pojo class, the last attribute annotated with @JsonProperty("store_condition"), which is also present in the above JSON. When the deserialization happens, it does not have this complete JSON object within the deserialize method, it only has the attributes after the store_condition attribute. But for my use case, I need to access the fields above that, for example, store_code. But since the store_code code is located before store_condition, the store_code does not available in the deserializer.

This is how I do the deserialization,

ObjectMapper mapper = new ObjectMapper();
Product product = mapper.convertValue(jsonInput, Product.class);

Could someone explain why and how this happens? Also, a way to solve this.
I hope that my question and my requirement is clear. Feel free to drop a comment if you need any clarifications.

The Jackson library I used is group: org.apache.beam , name: beam-sdks-java-extensions-json-jackson , version: 2.47.0

问题回答

the JsonParser is fetch data in sequence, when you invoke readValue, it get F, and the parser move its cursor to next token, so there is no method to access the store_code field that in the previous. so for your scenario, i think you could add custom deserializer for Product Class and maintaion all the field in your self, so you could no effect by the parse order.





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签