• 周四. 6月 30th, 2022

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

Jakson反序列化XML异常

admin

11月 28, 2021
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.travelsky.dto.av.rs.Seg` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('1')
 at [Source: (StringReader); line: 1, column: 242] (through reference chain: com.travelsky.dto.av.rs.OTA_AVE_RS["Response"]->com.travelsky.dto.av.rs.Out1["segs"]->com.travelsky.dto.av.rs.Segs["seg"]->java.util.ArrayList[0])
	at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
	at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1455)

模型为:

@XmlRootElement(name = "seg")
@AllArgsConstructor
@NoArgsConstructor
@JacksonXmlRootElement(localName = "seg")
@Data
public class Seg {
    @JsonProperty("routno")
    private String routno;
    @JsonProperty("subid")
    private String subid;
    //其他字段忽略
}

从异常信息上看起来是在提示Seg包含没有String参数的构造函数,但是因为我用了Lombok,使用了AllArgsConstructor注解,理论不上存在该问题。

于是查看MismatchedInputException异常,发现只有在xml反序列化结构匹配不上时才会抛出,于是设置xmlMapper的属性:

@Bean(name = "xmlMapper")
public XmlMapper jacksonXmlMapper() {
    XmlMapper mapper = new XmlMapper();
    mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
    mapper.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT,true);
    mapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL,true);
    return mapper;
}

重试后问题依旧存在。

于是上网搜索该异常可能的情况,最后在https://blog.csdn.net/neweastsun/article/details/100044167 一文中发现是模型定义的有一些问题。
问题不是出在Seg上,而是在Seg的上一级Segs。其最初的模型如下:

@XmlRootElement(name = "segs")
@JacksonXmlRootElement(localName = "segs")
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Segs {
    private List<Seg> seg;
}

修改成:

@XmlRootElement(name = "segs")
@JacksonXmlRootElement(localName = "segs")
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Segs {
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<Seg> seg;
}

问题解决。

发表评论

您的电子邮箱地址不会被公开。