2015-12-04 23 views
5

Tôi đang sử dụng Jackson để loại đa hình không đồng nhất từ ​​JSON. Tôi đang sử dụng các chú thích @JsonTypeInfo, @JsonSubTypes@JsonTypeName tương tự như Ví dụ 4 trong this post. Câu hỏi của tôi là, bây giờ tôi cần một người khác để mở rộng mã của tôi và thêm một lớp thứ ba: public class Duck extends Animal bên ngoài cơ sở mã ban đầu. Làm thế nào tôi có thể (hoặc những người khác) thêm thông tin SubType mà không sửa đổi mã nguồn (chú thích) của public abstract Animal class?Thêm thông tin SubType vào thời gian chạy sử dụng Jackson cho đa hình

CẬP NHẬT:

Tôi buộc phải sử dụng @JsonTypeName để giải quyết các thay đổi phiên bản POJO. Ví dụ:

package my.zoo; 
@JsonTypeInfo( 
    use = JsonTypeInfo.Id.NAME, 
    include = JsonTypeInfo.As.PROPERTY, 
    property = "type") 
@JsonSubTypes({ 
    @Type(value = Cat.class, name = "[email protected]"), 
    @Type(value = Dog.class, name = "[email protected]"), 
    @Type(value = Catv2.class, name = "[email protected]")}) 
public abstract class Animal { 
    ... 
} 

@JsonTypeName("[email protected]") 
public class Cat extends Animal { 
    ... 
} 

@JsonTypeName("[email protected]") 
public class Catv2 extends Animal { 
    ... 
} 

@JsonTypeName("[email protected]") 
public class Dog extends Animal { 
    ... 
} 

// in another java package/project 
package another.zoo; 
import my.zoo.*; 

@JsonTypeName("[email protected]") 
public class Dogv2 extends Animal { 
    ... 
} 

Bây giờ vấn đề tôi phải đối mặt là tôi không thể unmarshal một JSON có gõ tên "[email protected]" mà không cần thêm @Type(value = another.zoo.Dogv2.class, name = "[email protected]")}) đến lớp Animal. Vì vậy, làm điều này với chú thích rõ ràng là không thể. Có cách nào để làm điều này trong thời gian chạy không?

UPDATE 2:

Tôi chỉ tìm thấy this SO question với trường hợp sử dụng tương tự như/giống nhau. Mối quan tâm của tôi ở đây là việc sử dụng chú thích sẽ ngăn mọi người mở rộng/triển khai lớp/giao diện cơ sở của bạn. Tôi muốn một cách để duy trì khả năng mở rộng của lớp cơ sở/giao diện của tôi và đảm bảo rằng logic của tôi (un) marshalling sẽ làm việc với các loại bê tông trong tương lai.

Trả lời

3

Tôi đã sử dụng thư viện Reflections để tìm tất cả các loại phụ của lớp Animal và đăng ký phương thức JsonSubTypes với phương thức mapper.registerSubtypes(Class<?>... classes).

+0

Bạn đã làm gì với chú thích @JsonTypeInfo? Bạn đã sử dụng JsonTypeInfo.Id.NAME chưa? – ampofila

+0

@ampofila, mã mô hình được hiển thị trong mã mẫu. Các. Các cuộc gọi RegisterSubtypes() được thực hiện trong trình điều khiển ứng dụng trong quá trình khởi động. Jackson sẽ chăm sóc mọi thứ khi deserializing json. – derrdji

+0

Cảm ơn bạn đã trả lời nhanh chóng.Tuy nhiên tôi không chắc chắn làm thế nào để đánh chặn một dịch vụ REST (tôi có một bộ điều khiển mà mất như param giao diện và tự động unmarhsalls json gửi đến). Cách của bạn hoạt động khi tôi đọc một cái gì đó từ một tập tin nhưng nó không phù hợp với một yêu cầu POST bằng cách sử dụng REST. – ampofila

2

Không sử dụng @JsonSubTypes. Sử dụng @JsonTypeInfo#use với JsonTypeInfo.Id.CLASS để xác định loại cho tuần tự hóa và deserialization.

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "type") 
abstract class Animal { /* whatever */ } 

Jackson sau đó sẽ lưu trữ tên đủ điều kiện để sắp xếp lại đối tượng và sử dụng lại để xác định một lớp đích cho quá trình deserialization.

Bạn sẽ phải đảm bảo không có lớp con nào có thuộc tính có tên type.


Có thể thực hiện công việc này với @JsonSubTypes nhưng nó liên quan đến mixin và không phải là giải pháp duy trì.

+0

Cảm ơn mẹo! Tuy nhiên, tôi buộc phải sử dụng chú thích @JsonTypeName ("") như trong ví dụ được cập nhật. Có cách nào để làm việc với điều đó không? – derrdji

+0

@SotiriosDelimanolis Có, nhưng theo cách này bạn vẫn phải chuyển tên đầy đủ trong văn bản json (ví dụ: {"type": "my.class", "data": {...}}). Đúng? – ampofila

+0

@ampofila Trong thiết lập này, có. Có ['JsonTypeInfo.Id.Custom'] (http://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonTypeInfo.Id.html#CUSTOM) để có thêm tùy chọn. –

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