Библиотека Джексона JSON: как создать экземпляр класса с абстрактными полями, которые не могут получить доступ к его конкретному представлению?

Это те же вопросы, что и:

Библиотека Jackson JSON: как создать экземпляр класс, содержащий абстрактные поля

Тем не менее, его решение невозможно, так как мой абстрактный класс находится в другом проекте, чем конкретный.

Есть ли способ тогда?

ИЗМЕНИТЬ

Моя архитектура выглядит следующим образом:

public class UserDTO {

    ...
    private LanguageDTO lang;

}

Я отправляю этого пользователя объекта:

restTemplate.postForObject(this.getHttpCore().trim() + "admin/user/save/1/" + idUser, userEntity, UserDTO.class);

Затем я должен получить его в функции:

 @RequestMapping(value = "/save/{admin}/{idUser}", method = RequestMethod.POST)
    public String saveUserById(@RequestBody final UserEntity user, @PathVariable Integer idUser, @PathVariable boolean admin)

с UserEntity, определенным как:

public class UserEntity extends AbstractUserEntity {
    ...

}

public abstract class AbstractUserEntity {

    ...
    private AbstractLanguageEntity lang;
}

Я хотел бы знать, как я могу указать, что lang должен быть создан как LanguageEntity, тогда как абстрактные классы находятся в другом проекте.


person user1531797    schedule 19.11.2013    source источник


Ответы (3)


Это может работать, если вы можете настроить сериализацию объекта. См. пример здесь. Посмотрите в разделе «1.1. Глобальная типизация по умолчанию», чтобы установить значения по умолчанию для включения дополнительной информации в вашу строку JSON, в основном конкретный тип Java, который необходимо использовать при десериализации.

Поскольку кажется, что вам нужно сделать это для вашего сервлета Spring, вам нужно будет передать преобразователь сообщений Spring, как указано здесь

Затем внутри вашего пользовательского objectMapper вы можете выполнить необходимую настройку:

public class JSONMapper extends ObjectMapper {    
    public JSONMapper() {
        this.enableDefaultTyping();
    }    
}

Вероятно, вы могли бы также заставить его работать с Mix-ins, которые позволяют вам добавлять аннотации к уже определенным классам. Вы можете увидеть и пример здесь. Это также необходимо настроить внутри objectMapper.

Если вам нужна такая же функциональность на стороне клиента (шаблон REST), вы можете передать средство сопоставления объектов, как показано здесь.

person Andres Olarte    schedule 19.11.2013
comment
Извините, я не понимаю, как это сделать, учитывая мой контекст. Я обновил свой вопрос, чтобы дать более подробную информацию об этом. - person user1531797; 20.11.2013

Самый простой способ решить эту проблему — добавить геттеры и сеттеры в UserEntity, но указать конкретный класс:

public LanguageEntity getLang() {
   return (LanguageEntity) lang;
}

public void setLang(LanguageEntity language){
   this.lang = language
}
person user1531797    schedule 25.11.2013

Если все, чего вы хотите добиться, это отметить, что LanguageEntity является реализацией AbstractLanguageEntity, вы можете зарегистрировать это сопоставление через модуль:

SimpleModule myModule = new SimpleModule())
  .addAbstractTypeMapping(AbstractLanguageEntity.class,
    LanguageEntity.class);
ObjectMapper mapper = new ObjectMapper()
   .registerMdoule(myModule);
person StaxMan    schedule 18.05.2015