2012-05-03 8 views
0

Использование Jackson, как я могу сериализовать/десериализовать JSON одним приложением, используя один набор классов, но иметь другое приложение десериализовать тот же JSON и загружать различные реализации этих классов?Jackson - десериализация для другого типа

У меня есть (Spring MVC) веб-приложение, которое позволяет пользователям определять шаги в скрипте, которые, в свою очередь, будут выполняться в клиентском приложении. Шаги могут быть такими, как ShowDialogStep, с такими свойствами, как dialogText, или WaitStep с достоянием duration.

Клиентское приложение будет загружать коллекции шагов с сервера. Тем не менее, классы, созданные клиентом, должны иметь функциональные возможности для выполнения, такие как execute(), которые в случае WaitStep будут отслеживать, насколько далеко он ждет. Очевидно, что серверное приложение никогда не знает об этом, а в менее простых примерах логика выполнения/обновления шагов включает все зависимости от клиента.

Итак, повторим мне нужно: приложение

  • сервер для сопоставления классов 'Prototype' в формате JSON;
  • Клиентское приложение для чтения такое же JSON, но создает экземпляры конкретных для выполнения классов вместо прототипов.

Будет ли это то, что может быть настроен на стороне клиента картографа, возможно, если JSON был сериализован с использованием относительных имен классов (а не полностью квалифицированное), то десериализатор может быть сконфигурирован, чтобы посмотреть в другом пакете для реализаций с логикой выполнения в них?

ответ

3

Вы можете использовать этот подход:

На стороне сервера:

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, 
     include=JsonTypeInfo.As.PROPERTY, property="@type") 
class Prototype { 
... 
} 

objectMapper.registerSubtypes(
      new NamedType(Prototype.class, "Execution"), 
      ... 
); 

тогда это будет сериализовать экземпляр прототипа и добавить тип фасоли:

{ 
    "@type" : "Execution", 
    ... 
} 

на клиенте -side:

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, 
     include=JsonTypeInfo.As.PROPERTY, property="@type") 
class Execution { 
... 
} 

objectMapper.registerSubtypes(
      new NamedType(Execution.class, "Execution"), // the same name 
    .... 
); 
objectMapper.readValue(....); // will be deserialized to an Execution instance