2017-01-23 114 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情况下移动,否则'}'标记将保留在流中,并且它将关闭该枚举的父项。

所以你需要解析你的对象从'{'标记到'}'标记