简体   繁体   English

使用Jackson的反序列化器正确反序列化对象

[英]Correctly deserialize an object with deserializer with Jackson

I need a custom deserializer for casting a string in a complex POJO. 我需要一个自定义反序列化器,用于在复杂的POJO中强制转换字符串。 The deserialization works until the deserializer is used: in particular when the custom deserializer is used, the non-object properties of my object are not serialized. 反序列化在使用反序列化器之前一直有效:特别是在使用自定义反序列化器时,不会序列化我对象的非对象属性。

I have a restful web service that has a pojo as a parameter. 我有一个宁静的Web服务,它以pojo作为参数。

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

So my class PreventivoWs requires a fromString(String) method. 因此,我的类PreventivoWs需要一个fromString(String)方法。 Here the class definition: 这里是类的定义:

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

...
}

Inside the jsonObject i have an enumeration defined as 在jsonObject内部,我有一个枚举定义为

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

but this object require a deserializer to be converted: 但是此对象需要将反序列化器转换为:

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

and it is annotated on the property: 并在属性上加注:

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

The fromString method simply call the jackson ObjectMapper: fromString方法只需调用杰克逊ObjectMapper:

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

If the enum is not specified in the jsonString, it works fine: the object is deserialized perfectly; 如果未在jsonString中指定该枚举,则它将正常工作:该对象已完美反序列化; If i add the enum in the jsonString, all the object-properties are deserialized (email, cliente, partenza, destinazione,...) but the other properties are ignored (dataritiro,dataconsegna,tipoconsegna). 如果我在jsonString中添加枚举,则所有对象属性都将反序列化(电子邮件,cliente,partenza,destinazione等),但其他属性将被忽略(dataritiro,dataconsegna,tipoconsegna)。

Why? 为什么? The custom deserializer broke the standard process of deserialization? 定制的反序列化器打破了反序列化的标准过程?

UPDATE: the parsing process is interrupted when the custom deserializer take place: i moved the cliente property (which contains the particular enum) at the end of the json object: now the fields dataconsegna, dataritiro and so on are deserialised. 更新:自定义反序列化器发生时,解析过程被中断:我将cliente属性(包含特定的枚举)移到json对象的末尾:现在,对字段dataconsegna,dataritiro等进行了反序列化。

So the deserialization process ends up when the custom deserializer take place (even the cliente object is interrupted) 因此,自定义反序列化器发生时,反序列化过程结束(即使cliente对象被中断)

Solved! 解决了! As written in Jackson Wiki : Jackson Wiki所写:

must NOT process any token beyond value being deserialized (no more, or no less) 不得处理超出反序列化值的任何令牌(不得多或少)

So the problem was in the deserializer: you must stop when the END_OBJECT (}) is found, otherwhise the jsonParser go on until the end of the stream, consuming all the other tokens. 因此问题出在反序列化器中:您必须在找到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 have added the case condition END_OBJECT for consuming only the first '}' and close correctly the parsing of the enum object. 我添加了条件条件END_OBJECT,使其仅使用第一个'}',并正确关闭了enum对象的解析。 The return was moved in the END_OBJECT case because otherwise the '}' token will remain in the stream and it will go to close the parent of the enum. 返回是在END_OBJECT情况下移动的,因为否则,“}”令牌将保留在流中,并且它将关闭枚举的父级。

So you need to parse your object from '{' token to '}' token 因此,您需要将对象从“ {”令牌解析为“}”令牌

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java Jackson反序列化包含/不带有自定义反序列化器的对象列表的对象吗? - Java Jackson deserialize an object containing a list of object with/without custom Deserializer? 即使我添加了定制的反序列化器,杰克逊也无法将枚举反序列化为对象 - Jackson cannot deserialize enum as object even if I add customized deserializer 如何反序列化地图<String,Object>正确地在杰克逊 - How to Deserialize a Map<String,Object> correctly in Jackson 杰克逊反序列化没有在Custom Deserializer上调用反序列化 - Jackson Deserialization not calling deserialize on Custom Deserializer Jackson:自定义反序列化器:无法使用数组反序列化 XML - Jackson: custom deserializer: cannot deserialize XML with array 如何编写自定义的Jackson解串器,将包含原始json的json对象反序列化为单个对象? - How do I write a custom Jackson deserializer to deserialize a json object that contains raw json into a single object? 在Jackson中反序列化对象引用 - Deserialize object reference in Jackson Jackson 反序列化对象或数组 - Jackson deserialize object or array 使用 Jackson 反序列化 object - Deserialize object with Jackson 如何让Jackson在自定义反序列化器中反序列化嵌套对象 - How to let Jackson deserialize nested objects in custom deserializer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM