Castor XML升级遇异常:MarshalException与ValidationException
问题解答
1. 错误成因
这个错误的核心是Castor-XML 1.4.1对XML ID属性的校验规则远严于旧版0.9.53:
- 旧版Castor默认对ID属性的非空、唯一性校验宽松甚至关闭,即使XML中被标记为ID的字段为空,也能正常反序列化。
- 1.4.1版本默认启用了严格的XML Schema约束校验,当XML中某个被映射为ID的属性/字段为空值时,就会触发
ValidationException。 - 另外,如果XML内容因流处理错误(比如用错压缩流)导致解析出的内容异常,也会被Castor的校验逻辑判定为ID为空。
2. Castor-XML 1.4.1的特殊操作要求
相比0.9.53,1.4.1有几个关键的行为变更需要注意:
- 默认开启严格验证:默认启用XML Schema的全量校验(包括ID/IDREF、数据类型约束等),如果不需要严格校验,需要显式关闭:
或者在映射文件中针对特定类/字段关闭验证:Unmarshaller unmarshaller = new Unmarshaller(Abc.class); unmarshaller.setValidation(false); // 关闭全局验证 abc = (Abc) unmarshaller.unmarshal(reader);<class name="Abc" validate="false"> <!-- 字段配置 --> </class> - 映射文件兼容性调整:旧版映射文件中的一些隐式默认行为(比如
validate属性默认值)在1.4.1中被修改,建议检查映射文件的配置是否符合新版本要求。 - 依赖与包结构:1.4.1拆分了Castor的核心与XML模块,确保你的项目只引入
castor-xml依赖,避免与旧版castor-core冲突。
3. 是否与gzip反序列化代码有关?
是的,你的代码存在明显问题:
- 处理GZIP压缩文件应该使用
GZIPInputStream,而非ZipInputStream——ZipInputStream是用于读取ZIP归档包的,用它读取GZIP文件会导致流解析错误,读取的内容不是正确的XML文本,进而被Castor判定为ID为空。 - 正确的流处理代码应该是:
FileInputStream fis = new FileInputStream("abc.xml.gz"); GZIPInputStream gzipIn = new GZIPInputStream(fis); Reader reader = new InputStreamReader(gzipIn, StandardCharsets.UTF_8); // 建议指定字符编码 abc = (Abc) Abc.unmarshal(reader); - 旧版Castor可能对流内容的容错性更强,或者你之前的代码正确使用了
GZIPInputStream,升级时误写成ZipInputStream才触发了问题。
内容的提问来源于stack exchange,提问作者Berry
相关产品推荐
相关产品推荐

