2017-01-23 136 views
0

我需要一個自定義反序列化器來在複雜的POJO中投射字符串。反序列化一直運行直到使用反序列化器:特別是在使用自定義反序列化器時,我的對象的非對象屬性未被序列化。正確反序列化帶有反序列化器的對象與傑克遜

我有一個有pojo作爲參數的寧靜的web服務。

public PreventivoResponse calculate(@FormParam(value = "preventivo") PreventivoWs preventivo) throws Exception; 

所以我的類PreventivoWs需要fromString(String)方法。這裏類定義:

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
@JsonIgnoreProperties(ignoreUnknown = true) 
@JsonInclude(JsonInclude.Include.NON_NULL) 
public class PreventivoWs implements Serializable{ 
    private static final long serialVersionUID = -554141724349909424L; 
    private ClienteMultiSelect cliente; 

    private String riferimento; 
    private List<EmailWS> email; 

    private String dataritiro; 
    private String dataconsegna; 
    private Long tipoconsegna; 

    private IndirizzoWS partenza; 

    private IndirizzoWS destinazione; 

    List<ColloWs> colli; 

    HashMap<Long, String> services; 

... 
} 

裏面的JSONObject我有一個枚舉定義爲

{ 
    "value" : "A", 
    "text" : "Active" 
} 

但該對象需要串並轉換器轉換:

public class TipoPersonaFGJsonDeserializer extends JsonDeserializer<TipoPersonaFG> { 

@Override 
public TipoPersonaFG deserialize(JsonParser jsonParser, DeserializationContext context) 
     throws IOException, JsonProcessingException { 

    JsonToken currentToken = null; 
    while ((currentToken = jsonParser.nextValue()) != null) { 
     switch (currentToken) { 
      case VALUE_STRING: 
       switch (jsonParser.getCurrentName()) { 
        case "value": 
         String name = jsonParser.getText(); 
         return TipoPersonaFG.valueOf(name); 
       } 
       break; 
      default: 
       break; 
     } 
    } 
    return null; 
} 
} 

,它被標註上物業:

@JsonDeserialize(using = TipoPersonaFGJsonDeserializer.class) 
private TipoPersonaFG tipo; 

的fromString方法簡單地調用傑克遜ObjectMapper:

public static PreventivoWs fromString(String jsonString) throws IOException{ 
    ObjectMapper mapper = new ObjectMapper(); 
    PreventivoWs oggetto = mapper.readValue(jsonString, PreventivoWs.class); 
    return oggetto; 
} 

如果jsonString未指定枚舉,它工作正常:對象是完全反序列化; 如果我在jsonString中添加枚舉,所有對象屬性都被反序列化(email,cliente,partenza,destinazione,...),但其他屬性被忽略(dataritiro,dataconsegna,tipoconsegna)。

爲什麼?定製解串器打破了反序列化的標準過程?

UPDATE: 解析過程被中斷時,自定義串並轉換器發生:ⅰ移動cliente屬性(它包含特定枚舉)在JSON對象的末尾:現在字段dataconsegna,dataritiro等被deserialised 。

所以反序列化過程結束時,自定義解串器發生(甚至cliente對象中斷)

回答

0

解決了! 寫在Jackson Wiki

必須正確處理超越價值的任何令牌反序列化(沒有更多的,還是不會少)

所以,問題是在解串器:你必須停止END_OBJECT時( })被發現,另一方面jsonParser繼續直到流結束,消耗所有其他的令牌。

@Override 
public TipoPersonaFG deserialize(JsonParser jsonParser, DeserializationContext context) 
     throws IOException, JsonProcessingException { 

    JsonToken currentToken = null; 
    String name = null; 
    while ((currentToken = jsonParser.nextValue()) != null) { 
     switch (currentToken) { 
      case VALUE_STRING: 
       switch (jsonParser.getCurrentName()) { 
        case "value": 
         name = jsonParser.getText(); 
         break; 
       } 
       break; 
      case END_OBJECT: 
       if(name != null) 
        return TipoPersonaFG.valueOf(name); 
       else 
        return null; 
     } 
    } 
    return TipoPersonaFG.valueOf(name); 
} 

我已經加入的情況下條件END_OBJECT僅消耗第一「}」和正確地關閉枚舉對象的解析。返回已在END_OBJECT情況下移動,否則'}'標記將保留在流中,並且它將關閉該枚舉的父項。

所以你需要解析你的對象從'{'標記到'}'標記