使用Java jaxb处理bean生成xml中一些问题

来源:互联网 发布:gta5ol小丑捏脸数据 编辑:程序博客网 时间:2024/04/29 14:44
  1. 在使用jaxb从bean转换为xml过程中,默认会将bean中属性为null的属性过滤掉,如下:

@XmlAccessorType(XmlAccessType.FIELD)@XmlRootElement(name = "person")public class Person {     private String name;     private String address;     //getter, setter}
执行如下代码:

Person person = new Person();person.setName("Tom");JAXBContext context = JAXBContext.newInstance(Person.getClass());Marshaller marshaller = context.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");StringWriter result = new StringWriter();marshaller.marshal(person, result);
此时result内容为:

<person>   <name>Tom</name></person>

因address为null,jaxb在处理生成xml过程中将<address>元素过滤掉,但此时如果业务需求需要生成一个空的<address></address>则可以通过变通为marshaller对象在marshal前添加监听器,在监听器中通过反射的方式对bean中属性为null的字段赋默认值的方式解决该问题,如字段类型为String的可以对该字段赋空字符串:

marshaller.setListener(new MarshallerListener());StringWriter result = new StringWriter();marshaller.marshal(person, result);

MarshallerListener中代码如下:

import com.xinyuan.haze.common.utils.HazeStringUtils;import com.xinyuan.tender.entity.XmlChoiceFilter;import javax.xml.bind.Marshaller;import java.lang.reflect.Field;/** * 该监听器主要用来解决jaxb无法渲染字段为null的属性. * <p> *     在将Java类转换为xml片段时,默认jaxb会过滤属性值为null的属性,通过该监听器的{@link #beforeMarshal(Object)}方法,在渲染前 *     通过将属性赋值为空字符串来达到在生成的xml片段中包含该属性的功能. * </p> * <p> *     <strong>注意:</strong>默认处理{@link String}类型的字段. * </p> */public class MarshallerListener extends Marshaller.Listener {    public static final String BLANK_CHAR = "";    @Override    public void beforeMarshal(Object source) {        super.beforeMarshal(source);        Field[] fields = source.getClass().getDeclaredFields();        for (Field f : fields) {            f.setAccessible(true);            //获取字段上注解<pre name="code" class="java">                       try {                    if (f.getType() == String.class && f.get(source) == null) {                        f.set(source, BLANK_CHAR);                    }                } catch (IllegalAccessException e) {                    e.printStackTrace();                }        }    }}

添加上述代码后生成过的result如下:

<person>   <name>Tom</name>   <address></address></person>
注意:该解决方案使用反射,动态改变了对象运行时属性状态如:
f.setAccessible(true);
故该解决方案不是最佳,因暂未找到其它好的方案所以采用该途径处理.



0 0