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

一、日期字段格式化输出

1.1 xStream

 XStream x = new XStream();
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,下面是示例

 package com.cnblogs.yjmyzz.test;

 import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date; import javax.xml.bind.annotation.adapters.XmlAdapter; public class JaxbDateAdapter extends XmlAdapter<String, Date> {
static final String STANDARM_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; @Override
public Date unmarshal(String v) throws Exception {
if (v == null) {
return null;
} DateFormat format = new SimpleDateFormat(STANDARM_DATE_FORMAT);
return format.parse(v);
} @Override
public String marshal(Date v) throws Exception {
DateFormat format = new SimpleDateFormat(STANDARM_DATE_FORMAT);
return format.format(v);
}
}

然后要处理的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)方法

 package com.cnblogs.yjmyzz.test;

 import java.text.NumberFormat;
import java.util.Locale; import com.thoughtworks.xstream.converters.basic.DoubleConverter; public class DoubleToCurrencyStringConverter extends DoubleConverter { NumberFormat format; public DoubleToCurrencyStringConverter(Locale local) {
format = NumberFormat.getCurrencyInstance(local);
} public String toString(Object obj) {
return format.format(obj);
} }

然后这样使用:

         XStream x = new XStream();
x.registerConverter(new DoubleToCurrencyStringConverter(Locale.CHINA));

2.2 Jaxb

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

 package com.cnblogs.yjmyzz.test;

 import java.text.NumberFormat;
import java.util.Locale; import javax.xml.bind.annotation.adapters.XmlAdapter; public class JaxbNumberAdapter extends XmlAdapter<String, Number> { @Override
public Number unmarshal(String v) throws Exception {
if (v == null) {
return null;
}
NumberFormat format = NumberFormat.getCurrencyInstance(Locale.CHINA);
return format.parse(v);
} @Override
public String marshal(Number v) throws Exception {
NumberFormat format = NumberFormat.getCurrencyInstance(Locale.CHINA);
return format.format(v);
}
}

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

     @XmlJavaTypeAdapter(JaxbNumberAdapter.class)
public Double getAmount() {
return amount;
}

最后附一个完整的示例:

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

 package com.cnblogs.yjmyzz.test;

 import java.io.Serializable;
import java.util.Date; import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.thoughtworks.xstream.annotations.XStreamAlias; @XmlRootElement(name = "sample")
@XStreamAlias("sample")
public class Sample implements Serializable{ private static final long serialVersionUID = -6271703229325404123L; private Double amount; private Date createDate; @XmlJavaTypeAdapter(JaxbNumberAdapter.class)
public Double getAmount() {
return amount;
} public void setAmount(Double amount) {
this.amount = amount;
} @XmlJavaTypeAdapter(JaxbDateAdapter.class)
public Date getCreateDate() {
return createDate;
} public void setCreateDate(Date createDate) {
this.createDate = createDate;
} }

同时为了使用jaxb更方便,定义一个JaxbUtil辅助类

 package com.cnblogs.yjmyzz.util;

 import java.io.StringReader;
import java.io.StringWriter; import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller; public class JaxbUtil { public static String toXml(Object obj) {
return toXml(obj, "UTF-8", false);
} public static String toXml(Object obj, String encoding,
boolean isFormatOutput) {
String result = null;
try {
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
isFormatOutput);
marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding); StringWriter writer = new StringWriter();
marshaller.marshal(obj, writer);
result = writer.toString();
} catch (Exception e) {
e.printStackTrace();
} return result;
} @SuppressWarnings("unchecked")
public static <T> T toObject(String xml, Class<T> c) {
T t = null;
try {
JAXBContext context = JAXBContext.newInstance(c);
Unmarshaller unmarshaller = context.createUnmarshaller();
t = (T) unmarshaller.unmarshal(new StringReader(xml));
} catch (Exception e) {
e.printStackTrace();
} return t;
}
}

完整的单元测试如下:

 package com.cnblogs.yjmyzz.test;

 import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
import org.junit.Test;
import com.cnblogs.yjmyzz.util.JaxbUtil;
import com.thoughtworks.xstream.converters.basic.DateConverter;
import com.thoughtworks.xstream.XStream; public class XStreamAndJaxbTest { private Sample getSampleObj() {
Calendar c = Calendar.getInstance(Locale.CHINA);
c.set(2014, 9, 31, 0, 0, 0);
Sample obj = new Sample();
obj.setCreateDate(c.getTime());
obj.setAmount(1234.5678);
return obj;
} @Test
public void testXStream() {
XStream x = new XStream();
x.alias("sample", Sample.class);
x.registerConverter(new DateConverter("yyyy-MM-dd HH:mm:ss", null,
TimeZone.getTimeZone("GMT+8")));
x.registerConverter(new DoubleToCurrencyStringConverter(Locale.CHINA));
System.out.println("==> xstream ==>\n");
System.out.println(x.toXML(getSampleObj()));
System.out.println("\n\n");
} @Test
public void testJaxb() {
System.out.println("==> jaxb ==>\n");
System.out.println(JaxbUtil.toXml(getSampleObj(),"UTF-8",true));
System.out.println("\n\n");
} }

测试结果如下:

==> 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的更多相关文章

  1. Java中数字的格式化输出

    Java中数字的格式化输出 double d = 345.678; String s = "hello!"; int i = 1234; //"%"表示进行格式 ...

  2. JSTL标签库中fmt标签,日期,数字的格式化

    首先介绍日期的格式化:(不要嫌多哦) JSTL格式化日期(本地化) 类似于数字和货币格式化,本地化环境还会影响生成日期和时间的方式. <%@ page pageEncoding="UT ...

  3. Linux下date命令,格式化输出,时间设置

    date命令的帮助信息 [root@localhost source]# date --help用法:date [选项]... [+格式] 或:date [-u|--utc|--universal] ...

  4. JAXP使用Stax API时格式化输出XML

    最近项目中需要生成XBRL instance,对于XML读写和验证进行了一些学习.由于Stax API不支持格式化输出,默认全都写在一行上,网上也没有搜到现成的东西,自己写了一个格式化输出的帮助类. ...

  5. JS关于Date函数的格式化输出

    // 对Date的扩展,将 Date 转化为指定格式的String // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符, // 年(y)可以用 1-4 个占 ...

  6. 关于Json传递的日期/Date(数字)/解析

    在将DateTime类型的数据Json后传到前台展示,出现如下效果 ,在客户端如何解析呢?在jquery easyui 的字段中加一个格式化的函数调用.   { field: 'CreateTime' ...

  7. Python:数字的格式化输出

    >>> 'The value is {:0,.2f}'.format(x) 'The value is 1,234.57' 需要将数字格式化后输出,并控制数字的位数.对齐.千位分隔符 ...

  8. Python之数字的格式化输出

    需求: 将数字格式化后输出,并控制数字的位数.对齐.千位分隔符和其他的细节 x = 1234.56789 # Two decimal places of accuracy print(format(x ...

  9. Typescript日期Date如何做格式化字符串

    ·使用一个date-fns/format的库 安装npm i date-fns --save import format from 'date-fns/format'; const newdate = ...

随机推荐

  1. redis使用笔记

    mysql---select * from table where xx;insert into table(name1,name2..) values(value1,value2);delete f ...

  2. JavaScript(四)——DOM操作——Window.document对象

    一.找到元素: docunment.getElementById("id"):根据id找,最多找一个:    var a =docunment.getElementById(&qu ...

  3. 0011《SQL必知必会》笔记07 数据的插入、更新和删除

    1.插入完整的行或一部分:INSERT INTO 表名(列名1-n) VALUES (对应的值1-n) INSERT INTO products(prod_id, vend_id, prod_name ...

  4. 报表引擎API开发入门— EJB程序数据源

    我们前面讲了几个数据源,今天我们来讲一下EJB数据源,这篇讲完我们数据源这部分就讲完了.数据连接不需要直接访问数据库,而是使用EJB做为数据源.FR通过定义程序数据集使用EJB的相关类获取到EJB数据 ...

  5. monkeyrunner之安卓开发环境搭建(一)

    在学习monkeyrunner之前,让我们先搭建好eclipse安卓开发环境. 对于程序开发人员而言,eclipse并不陌生,它提供了一个非常广阔的平台来开发程序.同样也可以用它来开发android程 ...

  6. 大话设计模式C++版——表驱动法改造简单工厂

    上回<大话设计模式C++版——简单工厂模式>中指出了简单工厂模式的缺陷,即违背了开发—封闭原则,其主要原因是由于switch的判断结构的使用,使修改或添加新的对象时需要改动简单工厂类的代码 ...

  7. PHP实现文件上传下载——心在忙而已

    这一周都没有写什么东西,是啊,一周时间都没有学习太多新的东西,除了开车. 妈蛋啊,天天中午去学车然后两周没有午觉的日子还是很崩溃的,加上之后工作压力带来的心忙,宝宝不开心啊. 不过,也是自己不是那么能 ...

  8. plain framework 1 参考手册 入门指引之 代码风格

    代码风格 介绍 介绍 框架自身采用了google的C++风格,作者也鼓励在你的应用中使用此风格,有关此风格你可以查阅相关资料了解.下面是一段plain framework中的代码,以便大家参考: 你可 ...

  9. UVA 11800 Determine the Shape --凸包第一题

    题意: 给四个点,判断四边形的形状.可能是正方形,矩形,菱形,平行四边形,梯形或普通四边形. 解法: 开始还在纠结怎么将四个点按序排好,如果直接处理的话,有点麻烦,原来凸包就可搞,直接求个凸包,然后点 ...

  10. NOIP2000方格取数[DP]

    题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...