2014-10-31 14 views
8

Đây là Jackson 2.2.x.Làm thế nào để kích hoạt các cuộc gọi đến .serializeWithType() của một lớp thực hiện JsonSerializable trong Jackson?

Tôi có một lớp thực hiện JsonSerializable; có hai phương pháp để triển khai cho giao diện này, serialize()serializeWithType().

Tôi muốn kiểm tra {de,} tuần tự hóa của lớp này và tôi có thể kích hoạt các cuộc gọi đến serialize() dễ dàng; không, tuy nhiên, serializeWithType().

Các javadoc for this latter method nói rằng phương pháp này được gọi là

[...] khi loại thông tin bổ sung được dự kiến ​​sẽ được đưa vào serialization, cho deserialization sử dụng.

Tôi chỉ không hiểu điều này có nghĩa ...

Làm thế nào để tôi thiết lập một môi trường thử nghiệm để phương pháp này được gọi là? Lưu ý rằng JSON được tuần tự hóa có thể thuộc bất kỳ kiểu nào ngoại trừ đối tượng (ví dụ, boolean, number, string, array là tất cả các kiểu hợp lệ).

Trả lời

9

Phương pháp này được sử dụng khi bạn muốn sử dụng đa hình

public class A { 
    ... 
} 

public class B extends A { 
    ... 
} 

public class C extends A { 
    ... 
} 

Nếu bạn serialize một thể hiện của C và sau đó cố gắng deserialize các json kết quả nhưng chỉ biết rằng nó là một tiểu loại A:

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

Bạn cần một thứ cần lưu trữ trong JSON kết quả để giữ kiểu thực của đối tượng được tuần tự hóa.

Điều này có thể được bật hoặc sử dụng @JsonTypeInfo trên lớp học của bạn hoặc bằng cách gọi enableDefaultTyping trên ObjectMapper của bạn.

Đây là một trường hợp thử nghiệm mẫu sử dụng 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

Hãy thử sử dụng chú thích JsonTypeInfo trên lớp học của bạn. Nó sẽ kích hoạt gọi số serializeWithType(). Nó được sử dụng để lưu trữ thông tin về loại đó là cần thiết cho các loại đa hình hoặc liên kết kiểu trừu tượng và phù hợp với thực hiện cụ thể.

4

Jackson 2 is completely incompatible with Jackson 1, và JsonSerializableWithType (Bây giờ phản đối và không sử dụng được) là một giao diện từ Jackson 1 dẫn đến sự hiện diện của serializeWithType() ở Jackson 2.

serializeWithType() được gọi khi có thêm thông tin loại bổ sung, có nghĩa là chú thích (JsonTypeInfo) là chỉ định lớp property cho deserialization delega tion, khi đa hình được sử dụng.Phương pháp này sau đó sẽ được gọi với thông tin bổ sung loại trong một TypeSerializer, có thể được viết bằng một loại tiền tố:

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

Bằng cách chú thích lớp với @JsonTypeInfo, bạn sẽ có thể để xác định tuần tự với các loại thông tin:

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

Sau đó, các giá trị typeinttypefloat sẽ được thiết lập trong tài sản có tên type. Khi bạn deserialize một MyNumber, nó sẽ được dựa trên đa hình. Thomas Maurel's answer thể hiện một cách tiếp cận đơn giản để kiểm tra bằng cách tuần tự hóa đối tượng dưới dạng chuỗi và xóa bỏ nó.

Các vấn đề liên quan