2017-01-23 13 views
0

複雑なPOJOで文字列をキャストするためのカスタムデシリアライザが必要です。デシリアライザは、デシリアライザが使用されるまで動作します。特に、カスタムデシリアライザを使用する場合、オブジェクトの非オブジェクトプロパティはシリアル化されません。デシリアライザを使用してJacksonで正しくオブジェクトを逆シリアル化する

私はパラメータとして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; 
列挙型はjsonStringに指定されていない場合、それは正常に動作し、

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

:10

fromStringメソッドは、単にジャクソンObjectMapperを呼び出すオブジェクトが完全に直列化復元されます。 jsonStringにenumを追加すると、すべてのオブジェクトプロパティがデシリアライズされます(電子メール、クライアント、パート、destinazioneなど)が、他のプロパティは無視されます(dataritiro、dataconsegna、tipoconsegna)。

なぜですか?カスタムデシリアライザは、デシリアライズの標準プロセスを壊しましたか?

UPDATE:カスタムデシリアライザが発生したときに は、解析処理が中断された:私は、JSONオブジェクトの末尾に(特定の列挙型が含まれています)clienteプロパティを移動:ようになりましフィールドdataconsegna、dataritiroとが直列化復元されています。

カスタムデシリアライザは

答えて

0

が解決しよう(でもclienteオブジェクトが中断された)場所を取るときに、逆シリアル化プロセスが終わります! 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); 
} 

Iは、「}」のみ最初に消費する場合条件END_OBJECTを追加して、正しく列挙オブジェクトの解析を閉じます。戻り値はEND_OBJECTの場合に移動されました。そうでないと '}'トークンがストリームに残り、列挙の親を閉じるために移動します。

オブジェクトを '{'トークンから '}'トークンに変換する必要があります

関連する問題