使用JaxbDataFormat编组XJC生成类时如何保留空字段?
解决JAXB编组时输出未赋值字段为空标签的问题
这个问题我之前也碰到过,JAXB默认确实会把null值的字段忽略掉,不会输出到XML里。要实现你要的<field2></field2>这种空标签效果,有几种靠谱的方案,看你的场景选择:
方案一:通过XJC绑定文件修改生成类(推荐,一劳永逸)
如果你是用XJC从Schema生成Java类,最省心的方式是写一个绑定文件,让XJC生成类时就给String字段加上默认空字符串和对应注解,这样不用手动修改生成的代码。
- 创建
binding.xml文件,内容如下:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="2.1"> <!-- 全局配置:所有String类型字段默认初始化为空字符串 --> <jaxb:globalBindings> <jaxb:property> <jaxb:baseType name="java.lang.String"/> <jaxb:defaultValue></jaxb:defaultValue> </jaxb:property> </jaxb:globalBindings> <!-- 可选:针对特定类的特定字段单独配置(如果不需要全局的话) --> <jaxb:bindings schemaLocation="你的Schema文件路径.xsd" node="/xs:schema/xs:complexType[@name='version015v003']"> <jaxb:bindings node="./xs:sequence/xs:element[@name='field2']"> <jaxb:property> <jaxb:XmlElement defaultValue=""/> </jaxb:property> </jaxb:bindings> </jaxb:bindings> </jaxb:bindings>
- 用XJC生成类时指定这个绑定文件:
xjc -b binding.xml 你的Schema文件.xsd
这样生成的version015v003类里,未赋值的String字段会默认是空字符串,编组时自然就输出空标签了。
方案二:配置JaxbDataFormat并初始化空字符串(适合无法重新生成类的场景)
如果已经生成了类不想重新生成,那可以手动把对象中null的String字段设为空字符串,再配置JaxbDataFormat:
- 初始化对象时处理null字段:
version015v003 obj = new version015v003(); obj.setField1("something"); // 把null的String字段设为空字符串 if (obj.getField2() == null) { obj.setField2(""); }
如果字段多,可以用反射批量处理:
private static void fillEmptyStrings(Object obj) throws IllegalAccessException { for (Field field : obj.getClass().getDeclaredFields()) { if (field.getType().equals(String.class)) { field.setAccessible(true); if (field.get(obj) == null) { field.set(obj, ""); } } } } // 使用方式 fillEmptyStrings(obj);
- 配置JaxbDataFormat:
JaxbDataFormat jaxbDataFormat = new JaxbDataFormat(); jaxbDataFormat.setContextPath("你的生成类所在包路径"); // 设置Marshaller属性(可选格式化输出,核心是确保空字符串被正常编组) Map<String, Object> marshallerProps = new HashMap<>(); marshallerProps.put(Marshaller.JAXB_FORMATTED_OUTPUT, true); jaxbDataFormat.setMarshallerProperties(marshallerProps);
这样编组时,空字符串的字段就会输出<field2></field2>。
方案三:输出带xsi:nil的空元素(不推荐,不符合你的需求,但可以了解)
如果能接受<field2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>这种格式,那可以给字段加@XmlElement(nillable=true)注解,然后配置Marshaller:
marshallerProps.put(Marshaller.JAXB_NIL, true);
但这和你要的空标签格式不一样,所以除非特殊需求,不建议用这个。
内容的提问来源于stack exchange,提问作者Connor Blair
相关产品推荐
相关产品推荐

