前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >XStream、JAXB 日期(Date)、数字(Number)格式化输出xml

XStream、JAXB 日期(Date)、数字(Number)格式化输出xml

作者头像
菩提树下的杨过
发布2018-01-19 11:17:45
2.7K0
发布2018-01-19 11:17:45
举报
文章被收录于专栏:菩提树下的杨过

XStream、Jaxb是java中用于对象xml序列化/反序列化 的经典开源项目,利用它们将对象转换成xml时,经常会遇到日期(Date)、数字按指定格式输出的需求,下面是使用示例:

一、日期字段格式化输出

1.1 xStream

代码语言:javascript
复制
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,下面是示例

代码语言:javascript
复制
 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     @Override
13     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     @Override
23     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

代码语言:javascript
复制
    @XmlJavaTypeAdapter(JaxbDateAdapter.class) 
    public Date getCreateDate() {
        return createDate;
    }

注:不要在private上使用,最好将注解打在get方法上,否则有可能报错。

这里,再给一个List<T>类型的常见用法: @XmlElementWrapper(name="details") @XmlElement(name="detail") public List<FSUDetail> getDetails() {     return details; } 如果没有这二个注解,xml的结果类似: <root> ...  <details>...</details>     <details>...</details> ... </root> 加上这二个注释后,xml的结果类似: <root> ... <details>         <detail>...</detail>         <detail>...</detail>     </details>   ... </root>

二、数字格式化

假设我们要将一个Double型的成员,按中国货币的格式输出

2.1 xStream

默认的DoubleConverter满足不了要求,得从它派生一个子类来重写toString(Object obj)方法

代码语言:javascript
复制
 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 }

然后这样使用:

代码语言:javascript
复制
1         XStream x = new XStream();
2         x.registerConverter(new DoubleToCurrencyStringConverter(Locale.CHINA));

2.2 Jaxb

仍然是按Adapter的老路,定义一个专用的Adapter

代码语言:javascript
复制
 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     @Override
11     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     @Override
20     public String marshal(Number v) throws Exception {        
21         NumberFormat format = NumberFormat.getCurrencyInstance(Locale.CHINA);
22         return format.format(v);
23     }
24 }

然后在相关的Double字段的get方法上,用注解使用这个Adapter

代码语言:javascript
复制
1     @XmlJavaTypeAdapter(JaxbNumberAdapter.class) 
2     public Double getAmount() {
3         return amount;
4     }

最后附一个完整的示例:

为演示效果,先定义一个Dto类:

代码语言:javascript
复制
 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辅助类

代码语言:javascript
复制
 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 }

完整的单元测试如下:

代码语言:javascript
复制
 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     @Test
23     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     @Test
35     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>

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014-10-31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档