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

Writer:BYSocket(泥沙砖瓦浆木匠)

Reprint it anywhere u want.

文章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

122

<fontsize="4"face="宋体">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;

}

}

</font>

注册报文体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

<fontsize="4"face="宋体">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));

}

}  </font>

运行下测试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报文:

<?xmlversion="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

时间: 2024-08-26 06:38:06

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

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

转自:[CXF REST标准实战系列] 二.Spring4.0 整合 CXF3.0,实现测试接口 文章Points: 1.介绍RESTful架构风格 2.Spring配置CXF 3.三层初设计,实现WebService接口层 4.撰写HTTPClient 客户端,并实现简单调用 介绍RESTful架构风格 REST是REST之父Roy Thomas创造的,当时提出来了REST的6个特点:客户端-服务器的.无状态的.可缓存的.统一接口.分层系统和按需编码.其具有跨语言和跨平台的优势. REST是一

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

Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Reprint it anywhere u want. 文章Points: 1.介绍RESTful架构风格 2.Spring配置CXF 3.三层初设计,实现WebService接口层 4.撰写HTTPClient 客户端,并实现简单调用 介绍RESTful架构风格 REST是REST之父Roy Thomas创造的,当时提出来了REST的6个特点:客户端-服务器的.无状态的.可缓存的.统一接口.分层系

标准库系列之xml模块

Python标准库系列之xml模块 Python's interfaces for processing XML are grouped in the xml package. 带分隔符的文件仅有两维的数据:行和列.如果你想在程序之间交换数据结构,需要一种方法把层次结构.序列.集合和其他的结构编码成文本. XML是最突出的处理这种转换的标记(markup)格式,它使用标签(tag)分个数据,如下面的实例文件menu.xml所示: <?xml version="1.0" encod

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

[注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 1.Hive介绍 1.1 Hive介绍 Hive是一个基于Hadoop的开源数据仓库工具,用于存储和处理海量结构化数据.它是Facebook 2008年8月开源的一个数据仓库框架,提供了类似于SQL语法的HQL语句作为数据访问接口,Hive有如下优缺点: l  优点: 1.Hive 使用类SQL 查询语法, 最大限度的实现了和SQL标准的兼容,大大降低了传统数据分析人员学习的曲线: 2.使用JDBC

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

[注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送–Spark入门实战系列>获取 1 运行环境说明 1.1 硬软件环境 主机操作系统:Windows 64位,双核4线程,主频2.2G,10G内存 虚拟软件:VMware? Workstation 9.0.0 build-812388 虚拟机操作系统:CentOS 64位,单核 虚拟机运行环境: JDK:1.7.0_55 64位 Hadoop:2.2.0(需要编译为64位) Scala:2.10.4 Spark:1.1.0(需要编译)

WCF 开发实战系列 (一)

也许有读者会说,为什么要谈 WCF?近期不是 Web API 比较热门?在这个手机.Devices 当道的现在,究竟有什么地方会需要使用到 WCF 呢? 的确,现在访间你能找到的课程,或者您可能参与某项目的实践 (网页应用程序.手机 APP 也好),你需要的通常也都是提供 Services 层,而这个 Services 层通常也就是 Web API.那么,难道 WCF 就无用武之地?其实也不是,看什么情况用什么技术,有一些地方是 Web API 无法做到的 前言 也许有读者会说,为什么要谈 WC

R语言数据挖掘实战系列(5)

R语言数据挖掘实战系列(5)--挖掘建模 一.分类与预测 分类和预测是预测问题的两种主要类型,分类主要是预测分类标号(离散属性),而预测主要是建立连续值函数模型,预测给定自变量对应的因变量的值. 1.实现过程 (1)分类 分类是构造一个分类模型,输入样本的属性值,输出对应的类别,将每个样本映射到预先定义好的类别.分类模型建立在已有类标记的数据集上,模型在已有样本上的准确率可以方便地计算,所以分类属于有监督的学习. (2)预测 预测是建立两种或两种以上变量间相互依赖的函数模型,然后进行预测或控制.

Spark入门实战系列--8.Spark MLlib(上)--机器学习及SparkMLlib简介

[注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 1.机器学习概念 1.1 机器学习的定义 在维基百科上对机器学习提出以下几种定义: l“机器学习是一门人工智能的科学,该领域的主要研究对象是人工智能,特别是如何在经验学习中改善具体算法的性能”. l“机器学习是对能通过经验自动改进的计算机算法的研究”. l“机器学习是用数据或以往的经验,以此优化计算机程序的性能标准.” 一种经常引用的英文定义是:A computer program is said

《web 前端基础到实战系列课程》

<web 前端基础到实战系列课程> 摘要: mod_expires&mod_headers可以减少10%左右的重复请求,让重复的用户对指定的页面请求结果都CACHE在本地,根本不向服务器发出请求. 在使用之前,首先要确认一下"mod_expires"模组是否有启用.如果是自己安装Apache来架设网页主机的话,这里我们可以透过编辑Apache的"httpd.conf"设定档来处理 一.浏览器缓存原理 将该行前面的"#"字号删除