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

  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);
故该解决方案不是最佳,因暂未找到其它好的方案所以采用该途径处理.



评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值