2012-01-09 24 views
17

là nó có thể deserialize enums, trong đó có một chỉ số dựa trên một?Jackson - deserialize một cơ sở enums

enum Status { 
    Active, 
    Inactive 
} 

{status: 1} có nghĩa Status.Active, nhưng Jackson làm cho nó Status.Inactive :(

+1

Câu hỏi không liên quan gì đến việc tuần tự hóa –

+0

Giống như Oscar cho biết, liệt kê (và khoa học máy tính nói chung) là dựa trên 0. Trừ 1 từ số nếu đó là thứ bạn đang nhận từ một lớp khác. – rynmrtn

Trả lời

10

Bạn có thể tạo một kiểu tùy chỉnh deserialiser cho enum của bạn:

public enum Status { 
    ACTIVE, 
    INACTIVE; 
    public static Status fromTypeCode(final int typeCode) { 
     switch(typeCode) { 
     case 1: return ACTIVE; 
     case 2: return INACTIVE; 
     } 
     throw new IllegalArgumentException("Invalid Status type code: " + typeCode); 
    } 
} 

public class StatusDeserializer extends JsonDeserializer<Status> { 
    @Override 
    public Status deserialize(final JsonParser parser, final DeserializationContext context) throws IOException { 
     return Status.fromTypeCode(parser.getValueAsInt()); 
    } 
} 

Sau đó bạn có thể nói với Jackson sử dụng deserialiser tùy chỉnh của bạn cho một tài sản:

public class WarpDrive { 
    private Status status; 
    @JsonDeserialize(using = StatusDeserializer.class) 
    public void setStatus(final Status status) { 
     this.status = status; 
    } 
    public Status getStatus() { 
     return this.status; 
    } 
} 

Bạn cũng có thể cấu hình các đối tượng Jackson người lập bản đồ để sử dụng deserialiser tùy chỉnh của bạn cho tất cả các lần xuất hiện của loại mục tiêu. Xem http://wiki.fasterxml.com/JacksonHowToCustomDeserializers.

3

Enums có số ordinals, bắt đầu từ zero, và được gán cho mỗi giá trị trong một điều tra . theo thứ tự mà họ đã tuyên bố Ví dụ, trong mã của bạn Active có thứ tự 0Inactive có thứ tự 1 bạn có thể đi lại giữa giá trị của một enum và thứ tự của nó, như thế này:.

// ordinal=0, since Active was declared first in the enum 
int ordinal = Status.Active.ordinal(); 

// enumVal=Active, since 0 is the ordinal corresponding to Active 
Status enumVal = Status.values()[0]; 

Rõ ràng thứ tự 1 tương ứng với Inactive (nó không phải là một vấn đề Jackson), như đã giải thích ở trên, các đơn vị trong một liệt kê là không dựa trên. Có thể bạn nên sửa mã của mình để phản ánh điều đó và đảm bảo rằng {status:0} có nghĩa là Status.Active.

+1

Rõ ràng của nó, rằng 0 có nghĩa là Status.Active trong thế giới java! Nhưng nó không phải api của tôi, tôi chỉ thực hiện một khách hàng. Và api nói rằng 1 có nghĩa là hoạt động và 2 không hoạt động. Vì vậy, câu hỏi của tôi là, nếu tôi có thể làm cho Jackson biết về điều này. Có lẽ chỉ cần thêm một giá trị giả để dịch chuyển thứ tự một. – Dirk

+2

Không nên sử dụng Enum ordinals, ít sử dụng chúng trong serialization, bởi vì những thay đổi đối với định nghĩa Enum có thể thay đổi số thứ tự. – florian

44
public enum Status { 
ACTIVE(1), 
INACTIVE(2); 
private final int value; 
Status(int v) { 
    value = v; 
} 
@org.codehaus.jackson.annotate.JsonValue 
public int value() { 
    return value; 
} 
@org.codehaus.jackson.annotate.JsonCreator 
public static Status fromValue(int typeCode) { 
    for (Status c: Status.values()) { 
     if (c.value==typeCode) { 
      return c; 
     } 
    } 
    throw new IllegalArgumentException("Invalid Status type code: " + typeCode);   

}} 
+2

Đây thực sự là một giải pháp đơn giản hơn, thành ngữ hơn tôi. Cám ơn vì đã chia sẻ. – Nathan

+0

Đây cũng là một cách tuyệt vời để xử lý một vấn đề phổ biến của các bảng liệt kê được tuần tự hóa với cách viết hoa chưa biết. –

+0

nhưng nếu enum là bên thứ ba? – gstackoverflow

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