简体   繁体   中英

Polymorphic deserialization JSON by using POJOS

I want to consume a json with jax-rs my method stamp look like that.

@PostMapping("/test")
public ResponseEntity<String> consumeJson(@RequestBody TestPojo testPojo)

My json look like that

{
  "code": "<code>",
  "display": "<display>",
  "activities": [
    {
      "categoryCode": "drug",                
      "drugDisplay" : "Ceforanide"
    },{
      "categoryCode": "observation",       
      "measurementWeight" : "80kg",                     
    }
  ]

}

And i have the following pojos

public class TestPojo implements Serializable{
   private String code;
   private String display;
   private List<ActivityPojo> activities;

   // Getters & Setters
}

Now i have a super class and couple of classes inherit from it

public class ActivityPojo implements Serializable{
   private String categoryCode;
}

The child classes

public class DrugPojo extends ActivityPojo implements Serializable{
    private String drugDisplay;
    // Getters & Setters
}


public class ObservationPojo extends ActivityPojo implements Serializable{
    private String measurementWeight;
    // Getters & Setters
}

Inside my webservice method i want to do something like that

List<ActivityPojo> activities = testPojo.getActivities();
for(int i = 0; i < activities.size(); i++){
    if( activities.get(i) instanceof DrugPojo){
        // do stuff
    }
    else if( activities.get(i) instanceof ObservationPojo){
        // do stuff
    }
}

So can polymorphically serialize my json in order to do that. Any help would be appreciated.

This question is very interresting so I did a few tests.

If I understood correctly the problem, I think this class (and the inner one) can solve it :

@Component
@SuppressWarnings("serial")
public class ActivityPojoJsonModule extends SimpleModule {

    public ActivityPojoJsonModule() {
        this.addDeserializer(ActivityPojo.class, new ActivityPojoDeserializer());
    }

    public static class ActivityPojoDeserializer extends JsonDeserializer<ActivityPojo> {

        @Override
        public ActivityPojo deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
            ObjectCodec codec = parser.getCodec();
            JsonNode node = codec.readTree(parser);
            if(this.isDrug(node)) {
                return codec.treeToValue(node, DrugPojo.class);
            }
            return codec.treeToValue(node, ObservationPojo.class);
        }

        private boolean isDrug(JsonNode node) {
            return node.get("categoryCode").asText().equals("drug");
        }
    }
}

It adds a component to the Spring context that will deserialize ActivityPojo with a logic based on the value of the field categoryCode . You just have to add this class in the a scanned package and it will override the default behaviour of Jackson.

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