2014-10-31 1 views
8

Это Джексон 2.2.x.Как вызвать вызовы для .serializeWithType() класса, реализующего JsonSerializable в Jackson?

У меня есть класс, реализующий JsonSerializable; для этого интерфейса существуют два метода: serialize() и serializeWithType().

Я хочу проверить {de,} сериализацию этого класса, и я могу вызвать вызовы на serialize() легко; нет, однако, serializeWithType().

javadoc for this latter method говорит, что этот метод называется

[...] когда ожидается дополнительная информация типа, которые будут включены в сериализации для десериализации использовать.

Я просто не понимаю, что это значит ...

Как настроить тестовую среду, так что этот метод можно назвать? Обратите внимание, что JSON, который будет сериализован, может быть любого типа, кроме объекта (т. Е. Логические, числовые, строковые, массивные - все допустимые типы).

ответ

9

Этот метод используется, когда вы хотите использовать полиморфизм

public class A { 
    ... 
} 

public class B extends A { 
    ... 
} 

public class C extends A { 
    ... 
} 

Если вы сериализовать экземпляр C, а затем попытаться десериализации в результате JSON, но только зная, что его суб-тип A:

final ObjectMapper objectMapper = new ObjectMapper(); 
final String json = objectMapper.writeValueAsString(new C()); 
final A deserialized = objectMapper.readValue(json, A.class); 

Вам нужно что-то хранить в результирующем JSON, чтобы сохранить реальный тип сериализованного объекта.

Это может быть включено либо с использованием @JsonTypeInfo на вашем классе, либо по телефону enableDefaultTyping на вашем ObjectMapper.

Это тестовый образец случай, используя JUnit & Mockito

import com.fasterxml.jackson.databind.JsonSerializable; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import org.junit.Test; 

import static org.mockito.Matchers.any; 
import static org.mockito.Mockito.mock; 
import static org.mockito.Mockito.times; 
import static org.mockito.Mockito.verify; 

public class SerializeWithTypeTest { 

    private JsonSerializable serializable = mock(JsonSerializable.class); 

    @Test 
    public void shouldCallSerializeWithType() throws Exception { 
     final ObjectMapper objectMapper = new ObjectMapper().enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 

     objectMapper.writeValueAsString(serializable); 

     // make sure serializeWithType is called once 
     verify(serializable, times(1)).serializeWithType(any(), any(), any()); 

    } 

} 
2

Попробуйте использовать аннотацию JsonTypeInfo на свой класс. Он должен вызвать вызов serializeWithType(). Он используется для хранения информации о типе, которая требуется для полиморфных типов или для связывания абстрактного типа и соответствия конкретной реализации.

4

Джексон 2 is completely incompatible with Jackson 1 и JsonSerializableWithType (теперь устаревшим и непригодным для использования) является интерфейсом от Джексона 1, что привело к наличию serializeWithType() в Джексон 2.

serializeWithType() вызываются, когда, как ожидается, будет включена дополнительная информация типа, что означает, что аннотация (JsonTypeInfo) является указанием класса property для десериализации delega при использовании полиморфизма.Этот метод будет вызываться с информацией дополнительного типа в пределах TypeSerializer, которые могут быть записаны с префиксом типа:

/* (.., .., TypeSerializer typeSer) */ { 
    typeSer.writeTypePrefixForScalar(.., .., ThisClass.class); 
}

По аннотированию класса с @JsonTypeInfo, вы сможете указать сериализации с информацией типа:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, 
     include = As.WRAPPER_OBJECT, 
     property = "type") 
@JsonSubTypes({ 
     @Type(name = "typeint", value = MyInt.class), 
     @Type(name = "typefloat", value = MyFloat.class) 
}) 
public interface MyNumber {} 

@JsonTypeName("typeint") 
public MyInt implements MyNumber {} 

@JsonTypeName("typefloat") 
public MyFloat implements MyNumber {} 

Тогда значение typeint и typefloat будет установлено в свойстве с именем type. Когда вы deserialize MyNumber, он будет основан на полиморфизме. Thomas Maurel's answer демонстрирует простой подход к тестированию путем сериализации объекта как строки и его апробации.

Смежные вопросы