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     @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

    @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)方法

 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     @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

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     @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>

 

时间: 2025-01-20 13:55:10

XStream、JAXB 日期(Date)、数字(Number)格式化输出xml的相关文章

JS实现日期的格式化输出的例子

有时我们需要在 javascript 中对日期进行格式化,将其转换成固定格式的字符串.网上有许多现成的 JS 日期库可以使用,其实不借助这些库我们也可以自己实现. 1,对Date进行扩展 为方便我们对日期(Date)进行格式化输出,先对 Date 进行扩展,增加 format 方法.以后调用 Date 对象的 format 方法即可将日期转换成我们指定格式的字符串(String). Date.prototype.format = function (fmt) {   var o = {     

Linux date格式化输出时间和日期

  date命令参数 •-d, –date=STRING  显示STRING指定的时间 •-f, –file=DATEFILE  类似–date参数显示DATEFILE文件中的每行时间 •-ITIMESPEC, –iso-8601[=TIMESPEC]  以ISO  8601 格式显示日期/时间.TIMESPEC为"date"(只显示日期)."hours "."minutes"."senconds"(显示时间精度)之一,默认为

PHP 的 date() 函数用于格式化时间或日期

PHP Date() 函数 PHP Date() 函数可把时间戳格式化为可读性更好的日期和时间. 语法 date(format,timestamp) 参数 描述 format 必需.规定时间戳的格式. timestamp 可选.规定时间戳.默认是当前的日期和时间. PHP 日期 - 什么是时间戳(Timestamp)? 时间戳是自 1970 年 1 月 1 日(00:00:00 GMT)以来的秒数.它也被称为 Unix 时间戳(Unix Timestamp). PHP 日期 - 格式化日期 da

php使用date和strtotime函数输出指定日期的方法_php技巧

本文实例讲述了php使用date和strtotime函数输出指定日期的方法.分享给大家供大家参考.具体方法分析如下: 在php中date和strtotime函数都是对日期操作的,但是在生成上面date和strtotime是不一样的,一个是数字日期一个是 Unix 时间戳了,但我们都可以生成相同的日期,下面来看两个函数的例子. php中经常会用到date函数和strtotime函数,这2个函数大家一定并不陌生,今天和大家分享下使用技巧. strtotime - 将任何英文文本的日期时间描述解析为

php 格式化输出日期函数

php 格式化输出日期函数 public function format ($formatTo='standard',$timestamp = NULL) {   if ($timestamp!==NULL) {    $source = $timestamp;    if (!$source) {     return '';    }   } else {    $source = $this->timestamp;   }      switch (strtolower($formatTo

python中日期和时间格式化输出的方法小结

 这篇文章主要介绍了python中日期和时间格式化输出的方法,实例总结了Python常见的日期与事件操作技巧,非常具有实用价值,需要的朋友可以参考下     本文实例总结了python中日期和时间格式化输出的方法.分享给大家供大家参考.具体分析如下: python格式化日期时间的函数为datetime.datetime.strftime():由字符串转为日期型的函数为:datetime.datetime.strptime(),两个函数都涉及日期时间的格式化字符串,这里提供详细的代码详细演示了每一

python中日期和时间格式化输出的方法小结_python

本文实例总结了python中日期和时间格式化输出的方法.分享给大家供大家参考.具体分析如下: python格式化日期时间的函数为datetime.datetime.strftime():由字符串转为日期型的函数为:datetime.datetime.strptime(),两个函数都涉及日期时间的格式化字符串,这里提供详细的代码详细演示了每一个参数的使用方法及范例. 下面是格式化日期和时间时可用的替换符号 %a 输出当前是星期几的英文简写 >>> import datetime >&

C#数字格式化输出

  C#数字格式化输出       C#数字格式化输出 int a = 12345678; //格式为sring输出 Label1.Text = string.Format("asdfadsf{0}adsfasdf",a); Label2.Text = "asdfadsf"+a.ToString()+"adsfasdf"; Label1.Text = string.Format("asdfadsf{0:C}adsfasdf",

JDK5新特性:格式化输出

DK5.0允许象C语言那样直接用printf()方法来格式化输出,并且提供了许多参数来格式化输入,调用也很简单: System.out.format("Pi is approximately  %f", Math.Pi);    System.out.printf("Pi is approximately  %f", Math.Pi);  printf()和 format() 方法具有相同的功能. System.out 是 java.io.PrintStream的实