Вызов десериализатора по умолчанию в пользовательском десериализаторе не влияет на экземпляр - PullRequest
1 голос
/ 01 июня 2019

Я пытаюсь десериализовать Json в существующий экземпляр в моем процессе. Таким образом, он создает новый экземпляр, только если он не существует. Все объекты содержат идентификатор для их идентификации.

Я использовал этот ответ: https://stackoverflow.com/a/18405958/11584969 и попытался создать десериализатор custon для этого.

До сих пор мне удалось создать десериализатор custon, который проверяет существующие экземпляры, но я не смог заполнить новый экземпляр или изменить существующий.

Моя функция десериализации:

public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
  JsonNode node = jp.getCodec().readTree(jp);

  if (node instanceof NullNode) {
    return null;
  }

  // get id from node
  String strId = node.get("id").asText();
  UUID id = UUID.fromString(strId);

  // search for existing instance or create it
  T mObject = ...

  // fill/change instance
  return (T) defaultDeserializer.deserialize(jp, ctxt, mObject);
}

Создание картографа объекта:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enableDefaultTyping();
objectMapper.registerModule(new Jdk8Module());
objectMapper.registerModule(new JavaTimeModule());

SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier() {
  @Override
  public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
    if (beanDesc.getBeanClass() == Table.class)
      return new ModelObjectDeserializer<>(Table.class, (JsonDeserializer<Table>) deserializer);

    return deserializer;
  }
});
objectMapper.registerModule(module);

Приведенный выше код выполняется без каких-либо ошибок или исключений, но экземпляр из mObject не заполняется defaultDeserializer.deserialize (jp, ctxt, mObject);

Если я не использую свой собственный десериализатор, созданные экземпляры будут заполнены, как и ожидалось.

1 Ответ

0 голосов
/ 03 июня 2019

Это не совсем ответ на вопрос, но моя первоначальная цель была:

Я пытаюсь десериализовать Json в существующий экземпляр в моем процессе. Таким образом, он создает новый экземпляр, только если он не существует. Все объекты содержат идентификатор для их идентификации.

Для всех, кто пытается сделать то же самое, вот как я это реализовал:

public class ModelInstantiator extends StdValueInstantiator {

  private static final long serialVersionUID = -7760885448565898117L;

  private Class<? extends ModelObject> clazz;

  /**
   * @param config
   * @param valueType
   */
  public ModelInstantiator(DeserializationConfig config, Class<? extends ModelObject> clazz) {
    super(config, config.constructType(clazz));

    this.clazz = clazz;
  }

  @Override
  public boolean canCreateFromObjectWith() {
    return true;
  }

  @Override
  public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) throws IOException, JsonProcessingException {
    UUID id = (UUID) args[0];

    // get local object
    ModelObject object = ...

    // if id was not found => create and add
    if (object == null) {
      try {
        object = clazz.newInstance();
      } catch (InstantiationException | IllegalAccessException e) {
        throw new IOException(e);
      }

      object.setId(id);
      // add to local list
      ...
    }

    return object;
  }

  @Override
  public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) {
    CreatorProperty idProp = new CreatorProperty(new PropertyName("id"), config.constructType(UUID.class), null, null, null, null,
        0, null, PropertyMetadata.STD_REQUIRED);

    return new SettableBeanProperty[] { idProp };
  }

}

Мне пришлось разделить локальный идентификатор и идентификатор json. В противном случае идентификатор в массиве равен нулю.

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