![](/img/trans.png)
[英]Java Jackson deserialize an object containing a list of object with/without custom Deserializer?
[英]Correctly deserialize an object with deserializer with Jackson
我需要一个自定义反序列化器,用于在复杂的POJO中强制转换字符串。 反序列化在使用反序列化器之前一直有效:特别是在使用自定义反序列化器时,不会序列化我对象的非对象属性。
我有一个宁静的Web服务,它以pojo作为参数。
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中添加枚举,则所有对象属性都将反序列化(电子邮件,cliente,partenza,destinazione等),但其他属性将被忽略(dataritiro,dataconsegna,tipoconsegna)。
为什么? 定制的反序列化器打破了反序列化的标准过程?
更新:自定义反序列化器发生时,解析过程被中断:我将cliente
属性(包含特定的枚举)移到json对象的末尾:现在,对字段dataconsegna,dataritiro等进行了反序列化。
因此,自定义反序列化器发生时,反序列化过程结束(即使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);
}
我添加了条件条件END_OBJECT,使其仅使用第一个'}',并正确关闭了enum对象的解析。 返回是在END_OBJECT情况下移动的,因为否则,“}”令牌将保留在流中,并且它将关闭枚举的父级。
因此,您需要将对象从“ {”令牌解析为“}”令牌
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.