转自:[CXF REST标准实战系列] 一、JAXB xml与javaBean的转换

文章Points:

1、不认识到犯错,然后得到永久的教训。

2、认识JAXB

3、代码实战

1、不认识到犯错,然后得到永久的教训。

也不是所谓的教训吧,真正的教训来自于对错误的剖析理解很深刻。然后有种“吃一堑,长一智”的感觉才叫教训。近日和团队工头们用CXF3.0和Spring4.0开发一个平台,模仿着第三方支付,用xml进行数据交互。

因此,搜了下。果断用了dom4j,用自己键盘papa打了个叫做XmlOjbUtil的工具类。后来百度下,虽然不是万能的百度。但也要表扬下,发现人家搭着REST的CXF却集成了Jaxb。

果断抛弃了!(有时候决定就需要这么果断。)

先做个铺垫,我们先说下一些知识点:

CXF实现webService项目,有两种模式可以开发。Jax-ws实现经典的Web Service和Jax-rs实现REST标准。在Java EE 5/6中,Jaxb可以方便地集成,负责xml与JavaBean的映射。其实Jaxb也可以作为xml解析的一种技术。

2、认识JAXB

JAXB(Java Architecture for XML Binding)是根据XML Schema映射到JavaBean的技术。过程中,JAXB将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到 XML实例文档。

在JDK1.6时,JAXB 2.0是JDK 1.6的组成部分。JAXB 2.2.3是JDK 1.7的组成部分。

提前修一下文档知识吧:

JDK中JAXB相关的重要CLASS和INTERFACE:

1、JAXBContext类,是应用的入口,用于管理XML/Java绑定信息。

2、Marshaller接口,将Java对象序列化为XML数据。

3、Unmarshaller接口,将XML数据反序列化为Java对象。

JDK中JAXB相关的重要ANNOTATION:

1、@XmlType,将Java类或枚举类型映射到XML模式类型

2、@XmlAccessorType(XmlAccessType.FIELD) ,控制字段或属性的序列化。FIELD表示JAXB将自动绑定Java类中的每个非静态的(static)、非瞬态的(由@XmlTransient标注)字段到XML。其他值还有XmlAccessType.PROPERTY和XmlAccessType.NONE。

3、@XmlAccessorOrder,控制JAXB 绑定类中属性和字段的排序。

4、@XmlJavaTypeAdapter,使用定制的适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML。

5、@XmlElementWrapper ,对于数组或集合(即包含多个元素的成员变量),生成一个包装该数组或集合的XML元素(称为包装器)。

6、@XmlRootElement,将Java类或枚举类型映射到XML元素。

7、@XmlElement,将Java类的一个属性映射到与属性同名的一个XML元素。

8、@XmlAttribute,将Java类的一个属性映射到与属性同名的一个XML属性。

3、代码实战

我们既然要设计报文,所以我这边拿出来一个注册的Bean的设计。首先我们设计注册的Bean,代码如下:

DataBean.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package com.xidian.wq.imaopay.model.mesdata.base;
 
import javax.xml.bind.annotation.XmlRootElement;
 
/**
 *
 * @author BYSocket
 * 报文头-[报文基础信息]
 */
@XmlRootElement(name="data_bean")
public class DataBean
{
    // 版本信息(data_version)
    String version;
     
    ////消息类型(data_type)
    // 000001 - 注册[个人信息Post|Respose]
    // 000002 - 绑定银行卡[首次绑定,保存个人信息]
    // 000003 - 绑定银行卡[二次,校验个人信息]
    // 100001 - 支付[钱包支付]
    // 100002 - 查询
    // 200001
    String data_type;
     
    ////订单编号(order_id)
    // 总长20位, 有字母要用大写
    String batch_no;
     
    // 平台账号(platform_account)
    String user_name;
     
    ////请求状态
    // 000
    String trans_state;
     
    // 签名信息(msg_sign)
    String msg_sign;
 
    // 时间戳(randomTime)
    private String rd_time;
 
    // 随机数(randomNum)
    private String rd_num;
 
    // 密钥(keySign)
    private String k_sign;
     
    // 保留域
    String reserve;
 
    public String getVersion()
    {
        return version;
    }
 
    public void setVersion(String version)
    {
        this.version = version;
    }
 
    public String getData_type()
    {
        return data_type;
    }
 
    public void setData_type(String data_type)
    {
        this.data_type = data_type;
    }
 
    public String getBatch_no()
    {
        return batch_no;
    }
 
    public void setBatch_no(String batch_no)
    {
        this.batch_no = batch_no;
    }
 
    public String getUser_name()
    {
        return user_name;
    }
 
    public void setUser_name(String user_name)
    {
        this.user_name = user_name;
    }
 
    public String getTrans_state()
    {
        return trans_state;
    }
 
    public void setTrans_state(String trans_state)
    {
        this.trans_state = trans_state;
    }
 
    public String getMsg_sign()
    {
        return msg_sign;
    }
 
    public void setMsg_sign(String msg_sign)
    {
        this.msg_sign = msg_sign;
    }
 
    public String getRd_time()
    {
        return rd_time;
    }
 
    public void setRd_time(String rd_time)
    {
        this.rd_time = rd_time;
    }
 
    public String getRd_num()
    {
        return rd_num;
    }
 
    public void setRd_num(String rd_num)
    {
        this.rd_num = rd_num;
    }
 
    public String getK_sign()
    {
        return k_sign;
    }
 
    public void setK_sign(String k_sign)
    {
        this.k_sign = k_sign;
    }
 
    public String getReserve()
    {
        return reserve;
    }
 
    public void setReserve(String reserve)
    {
        this.reserve = reserve;
    }
 
}

RegBean.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package com.xidian.wq.imaopay.model.mesdata.base;
 
 
import javax.xml.bind.annotation.XmlRootElement;
 
/**
 *
 * @author BYSocket
 * 报文体-[用户注册报文体信息]
 */
@XmlRootElement(name="reg_bean")
public class RegBean
{
     
    // 注册报文体流水号(reg_data_sn)
    private String reg_sn;
     
    ////用户编号(user_info_id)
    // 业务系统的用户编号只做记录不在支付系统中逻辑处理
    private Integer user_id;
 
    // 注册账号(reg_account)
    private String reg_no;
     
    // 注册途径(reg_way)
    private String reg_way;
     
    // 保留域
    private String reserve;
     
    ////提交日期(set_time)
    // 业务系统上传
    private String set_time;
     
    // 后台信息返回路径(return_url)
    private String ret_url;
     
    // 备注
    String remarks;
 
    public String getReg_sn()
    {
        return reg_sn;
    }
 
    public void setReg_sn(String reg_sn)
    {
        this.reg_sn = reg_sn;
    }
 
    public Integer getUser_id()
    {
        return user_id;
    }
 
    public void setUser_id(Integer user_id)
    {
        this.user_id = user_id;
    }
 
    public String getReg_no()
    {
        return reg_no;
    }
 
    public void setReg_no(String reg_no)
    {
        this.reg_no = reg_no;
    }
 
    public String getReg_way()
    {
        return reg_way;
    }
 
    public void setReg_way(String reg_way)
    {
        this.reg_way = reg_way;
    }
 
    public String getReserve()
    {
        return reserve;
    }
 
    public void setReserve(String reserve)
    {
        this.reserve = reserve;
    }
 
    public String getSet_time()
    {
        return set_time;
    }
 
    public void setSet_time(String set_time)
    {
        this.set_time = set_time;
    }
 
    public String getRet_url()
    {
        return ret_url;
    }
 
    public void setRet_url(String ret_url)
    {
        this.ret_url = ret_url;
    }
 
    public String getRemarks()
    {
        return remarks;
    }
 
    public void setRemarks(String remarks)
    {
        this.remarks = remarks;
    }
 
}

注册报文体MsgRegBean.java,支持内容的列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.xidian.wq.imaopay.model.mesdata;
 
import java.util.List;
 
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
 
import com.xidian.wq.imaopay.model.mesdata.base.DataBean;
import com.xidian.wq.imaopay.model.mesdata.base.RegBean;
 
@XmlRootElement( name = "msg_bean" )
public class MsgRegBean
{
    private DataBean dataBean;
     
    private List<RegBean> regBeans;
 
     
    public DataBean getDataBean()
    {
        return dataBean;
    }
 
    @XmlElement(name = "data_bean")
    public void setDataBean(DataBean dataBean)
    {
        this.dataBean = dataBean;
    }
 
    @XmlElementWrapper(name = "reg_beans") 
    @XmlElement(name = "reg_bean")
    public List<RegBean> getRegBeans()
    {
        return regBeans;
    }
 
    public void setRegBeans(List<RegBean> regBeans)
    {
        this.regBeans = regBeans;
    }
 
}

然后针对的我们用Jaxb实现一个转换的Util类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package com.xidian.wq.imaopay.util;
import java.io.StringReader; 
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 
 
import com.alibaba.fastjson.JSON;
import com.xidian.wq.imaopay.model.mesdata.MsgRegBean;
import com.xidian.wq.imaopay.model.mesdata.base.DataBean;
import com.xidian.wq.imaopay.model.mesdata.base.RegBean;
 
/**
 *  
 * @author BYSocket
 * Jaxb2.0 处理Xml与Object转换
 *
 */
public class JaxbObjectAndXmlUtil
       
    /**
     * @param xmlStr 字符串
     * @param c 对象Class类型
     * @return 对象实例
     */
    @SuppressWarnings("unchecked")
    public static <T> T xml2Object(String xmlStr,Class<T> c)
    
        try
        
            JAXBContext context = JAXBContext.newInstance(c); 
            Unmarshaller unmarshaller = context.createUnmarshaller(); 
             
            T t = (T) unmarshaller.unmarshal(new StringReader(xmlStr)); 
             
            return t; 
             
        } catch (JAXBException e) {  e.printStackTrace();  return null; } 
         
    
       
    /**
     * @param object 对象
     * @return 返回xmlStr
     */
    public static String object2Xml(Object object)
    
        try
        {   
            StringWriter writer = new StringWriter();
            JAXBContext context = JAXBContext.newInstance(object.getClass()); 
            Marshaller  marshal = context.createMarshaller();
             
            marshal.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // 格式化输出 
            marshal.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");// 编码格式,默认为utf-8 
            marshal.setProperty(Marshaller.JAXB_FRAGMENT, false);// 是否省略xml头信息 
            marshal.setProperty("jaxb.encoding", "utf-8"); 
            marshal.marshal(object,writer);
             
            return new String(writer.getBuffer());
             
        } catch (Exception e) { e.printStackTrace(); return null;}    
         
    
     
    public static void main(String[] args)
    {
         /** 构造测试报文头对象 */
        DataBean dataBean = new DataBean();
        dataBean.setBatch_no("N20150204");
        dataBean.setData_type("000001");
        dataBean.setVersion("v1.0");
        dataBean.setUser_name("xx");
        dataBean.setMsg_sign("未知");
        dataBean.setRd_num("6631383");
        dataBean.setRd_time("20150204");
        dataBean.setK_sign("75CC479AAC09F00BA28F0E968B1BC9D1B90ADCC2");
 
        /** 构造测试报文体对象 */
        RegBean regBean = new RegBean();
        regBean.setReg_sn("REG20150204");
        regBean.setUser_id(12);
        regBean.setReg_no("33");
        regBean.setReg_way("pc");
        regBean.setSet_time("20150204 16:18");
        regBean.setRet_url("未知");
        regBean.setRemarks("无备注");
         
        MsgRegBean msgBean = new MsgRegBean();
        List<RegBean> regBeans = new ArrayList<RegBean>();
        regBeans.add(regBean);
        regBeans.add(regBean);
         
        msgBean.setRegBeans(regBeans);
        msgBean.setDataBean(dataBean);
         
        String xmlStr = JaxbObjectAndXmlUtil.object2Xml(msgBean);//构造报文 XML 格式的字符串
        System.out.println("对象转xml报文: \n"+xmlStr);
         
        MsgRegBean msgBean2 = JaxbObjectAndXmlUtil.xml2Object(xmlStr, MsgRegBean.class);
        System.out.println("报文转xml转: \n"+JSON.toJSONString(msgBean2));
    }
}

运行下测试main函数,可以得到如下的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
对象转xml报文:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<msg_bean>
    <data_bean>
        <batch_no>N20150204</batch_no>
        <data_type>000001</data_type>
        <k_sign>75CC479AAC09F00BA28F0E968B1BC9D1B90ADCC2</k_sign>
        <msg_sign>未知</msg_sign>
        <rd_num>6631383</rd_num>
        <rd_time>20150204</rd_time>
        <user_name>xx</user_name>
        <version>v1.0</version>
    </data_bean>
    <reg_beans>
        <reg_bean>
            <reg_no>33</reg_no>
            <reg_sn>REG20150204</reg_sn>
            <reg_way>pc</reg_way>
            <remarks>无备注</remarks>
            <ret_url>未知</ret_url>
            <set_time>20150204 16:18</set_time>
            <user_id>12</user_id>
        </reg_bean>
        <reg_bean>
            <reg_no>33</reg_no>
            <reg_sn>REG20150204</reg_sn>
            <reg_way>pc</reg_way>
            <remarks>无备注</remarks>
            <ret_url>未知</ret_url>
            <set_time>20150204 16:18</set_time>
            <user_id>12</user_id>
        </reg_bean>
    </reg_beans>
</msg_bean>
 
报文转xml转:
{"dataBean":{"batch_no":"N20150204","data_type":"000001","k_sign":"75CC479AAC09F00BA28F0E968B1BC9D1B90ADCC2","msg_sign":"未知","rd_num":"6631383","rd_time":"20150204","user_name":"xx","version":"v1.0"},"regBeans":[{"reg_no":"33","reg_sn":"REG20150204","reg_way":"pc","remarks":"无备注","ret_url":"未知","set_time":"20150204 16:18","user_id":12},{"reg_no":"33","reg_sn":"REG20150204","reg_way":"pc","remarks":"无备注","ret_url":"未知","set_time":"20150204 16:18","user_id":12}]}

代码中间注意点:
  Marshaller.JAXB_FORMATTED_OUTPUT :决定是否在转换成xml时同时进行格式化(即按标签自动换行,否则即是一行的xml) 。

Marshaller.JAXB_ENCODING :xml的编码方式。

Marshaller.JAXB_FRAGMENT :是否省略xml头信息

marshal.setProperty("jaxb.encoding", "utf-8"); : 设置编码格式 utf-8

[CXF REST标准实战系列] 一、JAXB xml与javaBean的转换(转)的更多相关文章

  1. [CXF REST标准实战系列] 二、Spring4.0 整合 CXF3.0,实现测试接口(转)

    转自:[CXF REST标准实战系列] 二.Spring4.0 整合 CXF3.0,实现测试接口 文章Points: 1.介绍RESTful架构风格 2.Spring配置CXF 3.三层初设计,实现W ...

  2. [CXF REST标准实战系列] 二、Spring4.0 整合 CXF3.0,实现测试接口

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Reprint it anywhere u want. 文章Points: 1.介绍RESTful架构 ...

  3. [CXF REST标准实战系列] 一、JAXB xml与javaBean的转换

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Reprint it anywhere u want. 文章Points: 1.不认识到犯错,然后得到 ...

  4. JAXB xml与javaBean的转换

    转自:https://blog.csdn.net/lydong_/article/details/79812626 `1. 1.不认识到犯错,然后得到永久的教训. 也不是所谓的教训吧,真正的教训来自于 ...

  5. GitHub实战系列~3.提交github的时候过滤某些文件 2015-12-10

    GitHub实战系列汇总:http://www.cnblogs.com/dunitian/p/5038719.html ———————————————————————————————————————— ...

  6. Spark入门实战系列--5.Hive(上)--Hive介绍及部署

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .Hive介绍 1.1 Hive介绍 月开源的一个数据仓库框架,提供了类似于SQL语法的HQ ...

  7. Spark入门实战系列--6.SparkSQL(下)--Spark实战应用

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .运行环境说明 1.1 硬软件环境 线程,主频2.2G,10G内存 l  虚拟软件:VMwa ...

  8. shiro实战系列(二)之入门实战续

    下面讲解基于实战系列一,所以相关的java文件获取pom.xml及其log4j文件同样适用于本次讲解. 一.Using Shiro Using Shiro 现在我们的 SecurityManager ...

  9. Jenkins持续集成企业实战系列之Jenkins配置演示-----03

    注:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.    最初接触Jenkins也是由于公司需求,根据公司需求Java代码项目升级的.(公司是 ...

随机推荐

  1. Latex 初学者入门(四)-- 多个作者共享同一个地址

    又给老板改格式,其实感觉大多会议都是模板不同,不同主要在于注释,作者,摘要以及引用文献的不同,上次的那篇讲bib数据库的用法,真是倒腾了一整天,不知道为什么一定要使用这种东西,而且老板貌似对人家的风格 ...

  2. C语言:字符串输出流输出文件中的数据。

    #include<stdio.h> #include<string.h> int main() { //定义文件指针 FILE *f = NULL; //打开文件 f = fo ...

  3. WhyGL:一套学习OpenGL的框架,及翻写Nehe的OpenGL教程

    最近在重学OpenGL,之所以说重学是因为上次接触OpenGL还是在学校里,工作之后就一直在搞D3D,一转眼已经毕业6年了.OpenGL这门手艺早就完全荒废了,现在只能是重学.学习程序最有效的办法是动 ...

  4. 第四章 第一个rabbitmq程序

    rabbitmq消息发送模型 要素: 生产者 消费者 交换器:生产者将消息发送到交换器 队列:交换器通过某种路由规则绑定到指定队列,将消息加入队列,消费者从队列消费消息 前提: 引入rabbitmq的 ...

  5. Spring MVC 4.2 CORS 跨域访问

    跨站 HTTP 请求(Cross-site HTTP request)是指发起请求的资源所在域不同于该请求所指向资源所在的域的 HTTP 请求.比如说,域名A(http://domaina.examp ...

  6. hdu 5326

    Work Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  7. 防止excel数字变成科学计数法

    在网上查了很多资料知道解决办法大概有两个:一是在身份证字段前加个英文单引号,二是设置Excel的格式为文本格式. 我试用过第一种确实可以显示,但是有个“'”号在那里感觉确实不是很好,虽然听说不影响,但 ...

  8. 隐马尔可夫模型HMM与维特比Veterbi算法(二)

    隐马尔可夫模型HMM与维特比Veterbi算法(二) 主要内容: 前向算法(Forward Algorithm) 穷举搜索( Exhaustive search for solution) 使用递归降 ...

  9. HAProxy的独门武器:ebtree

    1. HAProxy和ebtree简介 HAProxy是法国人Willy Tarreau个人开发的一个开源软件,目标是应对客户端10000以上的同时连接,为后端应用服务器.数据库服务器提供高性能的负载 ...

  10. C#.NET常见问题(FAQ)-如何批量增加或取消注释

    选中一批文本之后 批量增加注释:Ctrl+K Ctrl+C 批量取消注释:Ctrl+K Ctrl+U     更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.youku. ...