2012-01-09 55 views
17

是否有可能反序列化枚舉,其中有一個基於索引?傑克遜 - 反序列化一個基地枚舉

enum Status { 
    Active, 
    Inactive 
} 

{狀態:1}表示Status.Active,但傑克遜使得Status.Inactive :(

+1

問題無關係列化 – 2012-01-09 15:49:51

+0

像奧斯卡說,枚舉(和計算機科學一般)是從0開始的。如果您從另一圖層收到的東西,則從數字中減1。 – rynmrtn 2012-01-09 15:57:49

回答

10

您可以爲您的枚舉創建一個自定義類型解串器:

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()); 
    } 
} 

您可以再告訴傑克遜使用自定義解串器的屬性:

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; 
    } 
} 

您還可以配置傑克遜對象映射器使用您的自定義反序列化器來處理所有出現的目標類型。請參閱http://wiki.fasterxml.com/JacksonHowToCustomDeserializers

3

枚舉具有數字,在零開始,並且在枚舉會被分配給每一個值。在它們被聲明的順序。例如,在你的代碼Active有序0Inactive具有序1你可以來回走一個枚舉的價值和它的順序之間,像這樣:

// 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]; 

顯然序1對應於Inactive(它不是一個問題傑克遜),如上面所解釋的,在一個枚舉序是從零開始。也許你應該修正你的代碼以反映這一點,並確保{status:0}意味着Status.Active

+1

它清楚,0表示java世界中的Status.Active!但它不是我的api,我只是實現一個客戶端。並且api說1代表Active和2 Inactive。所以我的問題是,如果我能讓傑克遜知道這件事。 也許通過簡單地添加一個虛擬值來將序號移動一個。 – Dirk 2012-01-17 07:28:38

+2

不建議使用枚舉序列,更不用在序列化中使用它們,因爲對枚舉定義的更改可能會改變序數。 – florian 2015-03-25 16:42:14

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

這實際上是比我更簡單,更習慣的解決方案。感謝分享。 – Nathan 2013-04-26 02:28:02

+0

這也是處理序列化未知大小寫的枚舉常見問題的好方法。 – 2013-04-29 18:03:31

+0

但如果枚舉是第三方? – gstackoverflow 2015-07-31 13:59:30