Полиморфная десериализация JSON с использованием POJOS - PullRequest
0 голосов
/ 24 октября 2018

Я хочу использовать json с jax-rs, мой штамп метода выглядит следующим образом.

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

Мой json выглядит так

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

}

И у меня есть следующие pojos

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

   // Getters & Setters
}

Теперь у меня есть суперкласс и несколько классов наследуют его

public class ActivityPojo implements Serializable{
   private String categoryCode;
}

Дочерние классы

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


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

Внутри моего метода веб-сервиса я хочу сделатьчто-то в этом роде

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
    }
}

Так что я могу полиморфно сериализовать мой JSON, чтобы сделать это.Любая помощь будет оценена.

1 Ответ

0 голосов
/ 25 октября 2018

Этот вопрос очень интересен, поэтому я провел несколько тестов.

Если я правильно понял проблему, я думаю, что этот класс (и внутренний) может решить ее:

@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");
        }
    }
}

Он добавляет компонент в контекст Spring, который десериализует ActivityPojo с логикой, основанной на значении поля categoryCode.Вам просто нужно добавить этот класс в отсканированный пакет, и он переопределит поведение Джексона по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...