Jackson XML反序列化异常求助:无法构造实体类实例
解决Jackson XML反序列化无构造函数异常问题
这个异常的核心原因非常明确——Jackson在反序列化XML到Java/Kotlin对象时,找不到可以用来创建实例的构造函数。你当前的Assets、Asset、Permission类都只提供了带参数的构造函数,而Jackson默认需要无参构造函数来初始化对象,之后再通过setter方法为字段赋值。
解决方案1:添加无参构造函数
这是最直接的解决方式,给每个实体类都加上无参构造函数即可。
修改后的Assets类(Java):
@JacksonXmlRootElement(localName = "assets") public class Assets { @JacksonXmlElementWrapper(useWrapping = false) private Asset[] asset; // 新增无参构造函数 public Assets() {} public Assets(Asset[] asset) { this.asset = asset; } // 原有的getter和setter方法... }
同样的,给Asset、Permission、Group类都添加无参构造:
public class Asset { // 字段定义... public Asset() {} public Asset(String type, String name, String displayName, Permission[] permission) { // 原构造逻辑... } // getter和setter... }
如果是Kotlin类,写法如下:
@JacksonXmlRootElement(localName = "assets") class Assets { @JacksonXmlElementWrapper(useWrapping = false) var asset: Array<Asset>? = null // 无参构造 constructor() constructor(asset: Array<Asset>) { this.asset = asset } }
解决方案2:使用@JsonCreator标记构造函数
如果你不想添加无参构造,可以给带参数的构造函数加上@JsonCreator注解,并为每个参数用@JsonProperty指定对应的属性名,告诉Jackson用这个构造函数来创建实例。
示例(Java的Assets类):
@JacksonXmlRootElement(localName = "assets") public class Assets { @JacksonXmlElementWrapper(useWrapping = false) private Asset[] asset; @JsonCreator public Assets(@JsonProperty("asset") Asset[] asset) { this.asset = asset; } // getter和setter... }
Asset类的构造函数修改:
@JsonCreator public Asset( @JsonProperty("type") String type, @JsonProperty("name") String name, @JsonProperty("displayName") String displayName, @JsonProperty("permission") Permission[] permission ) { this.type = type; this.name = name; this.displayName = displayName; this.permission = permission; }
为什么序列化正常但反序列化失败?
序列化是从已有的对象生成XML,Jackson只需要调用对象的getter方法(或直接访问字段)来获取数据,不需要构造函数;而反序列化是从XML生成新对象,必须先创建实例,这时候就需要无参构造或者标记了@JsonCreator的构造函数来完成初始化。
选择任意一种方案修改后,你的反序列化代码val generated = objectMapper.readValue<Assets>(xmlAssets)就能正常工作了。
内容的提问来源于stack exchange,提问作者Wayne Hunter
相关产品推荐
相关产品推荐

