Castor 0.9.5.4反序列化XML至Java对象时id_car_PT字段值丢失
问题原因及解决方案
核心原因
Castor 0.9.5.4版本的默认字段-XML节点自动映射规则,无法正确处理id_car_PT这类「下划线后接连续大写字母」的命名结构。
Castor默认会尝试在Java字段名和XML节点名之间做自动转换(比如驼峰式与下划线分隔的互转),但对于id_car_PT这种包含下划线+多大写字母的命名,它的解析逻辑会出现匹配错误:无法将XML中的<id_car_PT>节点与Java类中对应的id_car_PT字段、getId_car_PT() getter方法关联起来,导致反序列化时无法赋值,最终显示为null。
而reg_car能正常工作,是因为它的结构是「下划线后接小写字母」,符合Castor默认转换规则的处理范围,自动映射可以成功匹配。
解决方案
方案1:使用Castor注解显式指定映射
在对应的Java字段上添加Castor的@XMLField注解,强制指定XML节点名,跳过自动映射逻辑:
修改ERT类:
import org.exolab.castor.xml.annotation.XMLField; import org.exolab.castor.xml.annotation.XMLRootElement; @XMLRootElement(name = "ERT") public class ERT { @XMLField(name = "id_car_PT") private String id_car_PT; // 原有的getter/setter方法保持不变 // ... }
修改Obj2类:
import org.exolab.castor.xml.annotation.XMLField; public class Obj2 { @XMLField(name = "id_car_PT") private String id_car_PT; // 原有的getter/setter方法保持不变 // ... }
方案2:使用Castor映射文件定义映射关系
如果不想修改Java类代码,可以创建映射文件(比如castor-mapping.xml),显式声明Java类与XML的对应关系:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http://castor.org/mapping.dtd"> <mapping> <!-- ERT类与XML根节点的映射 --> <class name="ERT"> <field name="id_car_PT" xml-name="id_car_PT" type="java.lang.String"/> <field name="obj1" type="Obj1"/> <field name="obj2" type="Obj2"/> </class> <!-- Obj2类的映射 --> <class name="Obj2"> <field name="id_car_PT" xml-name="id_car_PT" type="java.lang.String"/> </class> <!-- Obj1类的映射 --> <class name="Obj1"> <field name="reg_car" xml-name="reg_car" type="java.lang.String"/> </class> </mapping>
然后在反序列化时加载该映射文件:
import org.exolab.castor.mapping.Mapping; import org.exolab.castor.xml.Unmarshaller; import java.io.StringReader; public class Main { public static void main(String[] args) { try { String xml = "<ERT><id_car_PT>123</id_car_PT><obj1><reg_car>ABC123</reg_car></obj1><obj2><id_car_PT>456</id_car_PT></obj2></ERT>"; StringReader reader = new StringReader(xml); // 加载映射文件 Mapping mapping = new Mapping(Main.class.getClassLoader()); mapping.loadMapping("castor-mapping.xml"); Unmarshaller unmarshaller = new Unmarshaller(ERT.class); unmarshaller.setMapping(mapping); ERT ert = (ERT) unmarshaller.unmarshal(reader); System.out.println(ert.getId_car_PT()); System.out.println(ert.getObj1().getReg_car()); System.out.println(ert.getObj2().getId_car_PT()); } catch (Exception e) { e.printStackTrace(); } } }
内容的提问来源于stack exchange,提问作者Carlos Arias
相关产品推荐
相关产品推荐

