首页 > 代码库 > XStream、JAXB 日期(Date)、数字(Number)格式化输出xml
XStream、JAXB 日期(Date)、数字(Number)格式化输出xml
XStream、Jaxb是java中用于对象xml序列化/反序列化 的经典开源项目,利用它们将对象转换成xml时,经常会遇到日期(Date)、数字按指定格式输出的需求,下面是使用示例:
一、日期字段格式化输出
1.1 xStream
1 XStream x = new XStream();2 x.registerConverter(new DateConverter("yyyy-MM-dd HH:mm:ss", null,TimeZone.getTimeZone("GMT+8")));
xStream默认使用UTC时间格式输出,上面的代码演示了如何按北京时间输出 yyyy-MM-dd HH:mm:ss 格式
1.2 jaxb
jaxb处理这个要麻烦一点,先要创建一个Adapter,下面是示例
1 package com.cnblogs.yjmyzz.test; 2 3 import java.text.DateFormat; 4 import java.text.SimpleDateFormat; 5 import java.util.Date; 6 7 import javax.xml.bind.annotation.adapters.XmlAdapter; 8 9 public class JaxbDateAdapter extends XmlAdapter<String, Date> {10 static final String STANDARM_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";11 12 @Override13 public Date unmarshal(String v) throws Exception {14 if (v == null) {15 return null;16 }17 18 DateFormat format = new SimpleDateFormat(STANDARM_DATE_FORMAT);19 return format.parse(v);20 }21 22 @Override23 public String marshal(Date v) throws Exception {24 DateFormat format = new SimpleDateFormat(STANDARM_DATE_FORMAT);25 return format.format(v);26 }27 }
然后要处理的dto类,相应的Date字段的get方法上使用刚才这个Adapter
@XmlJavaTypeAdapter(JaxbDateAdapter.class) public Date getCreateDate() { return createDate; }
注:不要在private上使用,最好将注解打在get方法上,否则有可能报错
二、数字格式化
假设我们要将一个Double型的成员,按中国货币的格式输出
2.1 xStream
默认的DoubleConverter满足不了要求,得从它派生一个子类来重写toString(Object obj)方法
1 package com.cnblogs.yjmyzz.test; 2 3 import java.text.NumberFormat; 4 import java.util.Locale; 5 6 import com.thoughtworks.xstream.converters.basic.DoubleConverter; 7 8 public class DoubleToCurrencyStringConverter extends DoubleConverter { 9 10 NumberFormat format;11 12 public DoubleToCurrencyStringConverter(Locale local) {13 format = NumberFormat.getCurrencyInstance(local);14 }15 16 public String toString(Object obj) {17 return format.format(obj);18 }19 20 }
然后这样使用:
1 XStream x = new XStream();2 x.registerConverter(new DoubleToCurrencyStringConverter(Locale.CHINA));
2.2 Jaxb
仍然是按Adapter的老路,定义一个专用的Adapter
1 package com.cnblogs.yjmyzz.test; 2 3 import java.text.NumberFormat; 4 import java.util.Locale; 5 6 import javax.xml.bind.annotation.adapters.XmlAdapter; 7 8 public class JaxbNumberAdapter extends XmlAdapter<String, Number> { 9 10 @Override11 public Number unmarshal(String v) throws Exception {12 if (v == null) {13 return null;14 }15 NumberFormat format = NumberFormat.getCurrencyInstance(Locale.CHINA);16 return format.parse(v);17 }18 19 @Override20 public String marshal(Number v) throws Exception { 21 NumberFormat format = NumberFormat.getCurrencyInstance(Locale.CHINA);22 return format.format(v);23 }24 }
然后在相关的Double字段的get方法上,用注解使用这个Adapter
1 @XmlJavaTypeAdapter(JaxbNumberAdapter.class) 2 public Double getAmount() {3 return amount;4 }
最后附一个完整的示例:
为演示效果,先定义一个Dto类:
1 package com.cnblogs.yjmyzz.test; 2 3 import java.io.Serializable; 4 import java.util.Date; 5 6 import javax.xml.bind.annotation.XmlRootElement; 7 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 8 import com.thoughtworks.xstream.annotations.XStreamAlias; 9 10 @XmlRootElement(name = "sample")11 @XStreamAlias("sample")12 public class Sample implements Serializable{ 13 14 private static final long serialVersionUID = -6271703229325404123L;15 16 private Double amount;17 18 19 private Date createDate;20 21 @XmlJavaTypeAdapter(JaxbNumberAdapter.class) 22 public Double getAmount() {23 return amount;24 }25 26 public void setAmount(Double amount) {27 this.amount = amount;28 }29 30 @XmlJavaTypeAdapter(JaxbDateAdapter.class) 31 public Date getCreateDate() {32 return createDate;33 }34 35 public void setCreateDate(Date createDate) {36 this.createDate = createDate;37 }38 39 }
同时为了使用jaxb更方便,定义一个JaxbUtil辅助类
1 package com.cnblogs.yjmyzz.util; 2 3 import java.io.StringReader; 4 import java.io.StringWriter; 5 6 import javax.xml.bind.JAXBContext; 7 import javax.xml.bind.Marshaller; 8 import javax.xml.bind.Unmarshaller; 9 10 public class JaxbUtil {11 12 public static String toXml(Object obj) {13 return toXml(obj, "UTF-8", false);14 }15 16 public static String toXml(Object obj, String encoding,17 boolean isFormatOutput) {18 String result = null;19 try {20 JAXBContext context = JAXBContext.newInstance(obj.getClass());21 Marshaller marshaller = context.createMarshaller();22 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,23 isFormatOutput);24 marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);25 26 StringWriter writer = new StringWriter();27 marshaller.marshal(obj, writer);28 result = writer.toString();29 } catch (Exception e) {30 e.printStackTrace();31 }32 33 return result;34 }35 36 @SuppressWarnings("unchecked")37 public static <T> T toObject(String xml, Class<T> c) {38 T t = null;39 try {40 JAXBContext context = JAXBContext.newInstance(c);41 Unmarshaller unmarshaller = context.createUnmarshaller();42 t = (T) unmarshaller.unmarshal(new StringReader(xml));43 } catch (Exception e) {44 e.printStackTrace();45 }46 47 return t;48 }49 }
完整的单元测试如下:
1 package com.cnblogs.yjmyzz.test; 2 3 import java.util.Calendar; 4 import java.util.Locale; 5 import java.util.TimeZone; 6 import org.junit.Test; 7 import com.cnblogs.yjmyzz.util.JaxbUtil; 8 import com.thoughtworks.xstream.converters.basic.DateConverter; 9 import com.thoughtworks.xstream.XStream;10 11 public class XStreamAndJaxbTest {12 13 private Sample getSampleObj() {14 Calendar c = Calendar.getInstance(Locale.CHINA);15 c.set(2014, 9, 31, 0, 0, 0);16 Sample obj = new Sample();17 obj.setCreateDate(c.getTime());18 obj.setAmount(1234.5678);19 return obj;20 }21 22 @Test23 public void testXStream() { 24 XStream x = new XStream();25 x.alias("sample", Sample.class); 26 x.registerConverter(new DateConverter("yyyy-MM-dd HH:mm:ss", null,27 TimeZone.getTimeZone("GMT+8"))); 28 x.registerConverter(new DoubleToCurrencyStringConverter(Locale.CHINA));29 System.out.println("==> xstream ==>\n");30 System.out.println(x.toXML(getSampleObj()));31 System.out.println("\n\n");32 }33 34 @Test35 public void testJaxb() {36 System.out.println("==> jaxb ==>\n");37 System.out.println(JaxbUtil.toXml(getSampleObj(),"UTF-8",true));38 System.out.println("\n\n");39 }40 41 }
测试结果如下:
==> jaxb ==>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sample>
<amount>¥1,234.57</amount>
<createDate>2014-10-31 00:00:00</createDate>
</sample>
==> xstream ==>
<sample>
<amount>¥1,234.57</amount>
<createDate>2014-10-31 00:00:00</createDate>
</sample>
XStream、JAXB 日期(Date)、数字(Number)格式化输出xml