jaxb替换smooks项目方案建议书

久未见 提交于 2019-12-05 23:48:01


1 前言


         本文档是描述Smooks的应用情况,以及使用Jaxb替换smooks的可行性分析及实施方案,有不足之处还望谅解和指出。


2 背景


项目系统中使用Smooks出现几次死锁问题导致系统宕机,其后针对Smooks进行性能测试,同时,与jaxb进行了对比,发现Smooks存在严重的性能瓶颈的问题。

20个用户并发操作的测试数据:

50个用户并发操作的测试数据:

最终结果:

在20个用户并发操作情况下:

1、smooks各项指标都低于jaxb


在50个用户并发操作情况下:
1、smooks存在性能瓶颈问题,吞吐量下滑很严重,过程中出现了三次的不同时间的内容溢出(加载config文件导致的)。

2、jaxb的吞吐量变化不大,但平均处理时长多了4秒,比较稳定。

注:测试过程中包含了读取报文的时间(即从文件中获取报文数据,而后通过XMLBind技术进行转换),虽然时间有所偏差,但是,不影响整体测试结果。


3 Smooks的应用情况


3.1 集中式管理结构


目前,有关smooks的技术框架的使用,集中在VOS系统的销售服务层,也就是vos-app-sale-service

如下图所示:


如果使用其他技术比如Jaxb进行替换Smooks,可以在此层可以完成即可实现。其中,vos-app-sale-service层提供了每个javabeanxml进行提供了可输入的报文,使操作更加透明。


3.2 数据类型应用


Smooks由于它仅支持String的java引用类型对象,在我们vos当中使用与xml进行绑定的Javabean的属性都是为java.lang.String,同时,每个属性的值(String类型)都不能为null,必须要一个默认空字符"",这样转换过程中才不会报错。这个局限是因为Smooks本身问题而存在的,而VOS系统把这个作为了开发规范,采用默认字符串进行属性数据与XML绑定了。

示例代码

在这点来说,Jaxb相对比较灵活点。

1、Jaxb支持基本数据类型

2、支持对引用类型向基本数据类型正反的转换比如java.util.Date,此功能需要配置jaxb的适配器完成的。

3、Jaxb对引用类型的对象(包括了String),如果属性是引用类型,那么如果为null情况,Jaxb是不会把该字段与XML进行绑定的,就是说在XML里面看不到该字段。

对我们来说,第三点是争议比较多的,不同场景取决于不同的用法,怎么使用需要根据实际情况来判进行决策选择。但事实上,我们VOS中对javabeanxml转换如果字段属性出现null情况,默认需要在xml打印改字段的,这个前提条件是字段类型是String


3.3 动态支持


Smooks是通过javabean与xml之间关联文件config进行互相转换的。VOS系统也为了每个javabean与xml互相转换提供了config文件配置,并且是集中管理。




如上图示,划红线区域的是vos有关smookconfig文件管理路径。

Smooksjavabeanxml互转的提供了最基本转换的同时,也支持动态的转换方式,主要体现config文件可以使用模板引擎技术freemaket

VOS中对smooks的动态支持是采用freemaket对其config进行处理完成的。


Jaxb对于动态支持是它薄弱的环节,从它本身来说,Jaxb主要是通过注解来实现JavaBeanXML的转换。所以,对注解来说,是需要编译而后无法改变的。当然也可以使用一些第三方包通过改变class字节码来实现,但这个方案尚未得到普通应用,风险比较大。

Jaxb是静态的支持,Jaxb需要替换Smooks需要考虑这部分移植的可能性,是否可以通过其他途径来完成目的。答案是肯定的,对于交换报文来说,报文本是就是静态的,为了更好抽象我们业务模型,支持动态报文,是基于重用的目的,但是,从单一职责和业务模型来说,解耦是一个大问题,面向服务肯定需要松耦合。


Jaxb替换smooks的可行性分析


针对Smooks的应用情况,从集中式管理结构和数据类型应用来说,Jaxb是实现替换Smooks是没有问题的。但考虑到Smooks的动态支持,需要耗费一些时间开来进行动态支持转换。从技术角度出发,是可行的。

    必要考虑到风险分析:

    1、其一、涉及到销售核心模块,任何差错都可能引起一些大的问题。

    2、其二、涉及面广,虽然是集中,改动面积确实很大,config文件就有122个。

    3、其三、技术要求更多,要求技术人员既要熟悉smooks,也要熟悉jaxb

    4、其四、销售业务开发熟悉,不容易出错。

    5、其五、需要测试人员进行回归测试。

5 Jaxb替换smooks技术实施


Jaxb替换smooks具体实施过程,主要目标是降低风险,平滑化进行技术切换,可根据目前紧急程度,进行具体实施过程决策选择。

         具体实施过程保障:

         1、需要开发人员进行smooksjaxb的技术培训。

         2、提供jaxb相关的技术基础设施,比如转换工具类,数据类型适配器等。

         3、兼容两种技术,一旦出现重大情况,需要进行回退。

 

         具体实施建议参考:

         1、以点到点就行操作,确保每一步修改都没有问题。

         2、对存在比较严重问题区域优先处理。

         如果人数充足支持下时间的情况下,可以进行大范围推土机方式进行处理,短时间就可以出结果,风险高。

        如果人数不多支持下时间足够的情况下,可以进行循环渐进方式进行处理,优先对主要的问题区域进行实施,这样操作的目的,将风险降到最低,可进可退,效率高。


6 Jaxb技术介绍


6.1 简介


JAXB(Java API for XML Binding),是一个业界的标准,提供了一个快速便捷的方式将Java对象与XML进行转换。

JAX-WSJavaWebService规范之一)中,JDK1.6 自带的版本JAX-WS2.1,其底层支持就是JAXB

JAXB 2.0 基于 JSR 175 编程注释工具定义的程序注释。


6.2 JDK环境


JAXB 2.0是JDK 1.6的组成部分。JAXB 2.2.3是JDK 1.7的组成部分。

如果使用JDK 1.5单独下载JAXBRI即可,JAXB不支持JDK 1.4。

Jaxb官方地址

https://jaxb.java.net/


6.3 开发指南


6.3.1 JavaBean开发


JaveBean必须实现java.io.Serializable序列化接口,在头部地方必须注解@XmlRootElement


6.3.2 java2xml


实现对JaveBean转换成XML的实现过程。

public static String java2xml(Object obj) {
		try {
			JAXBContext content = JAXBContext.newInstance(obj.getClass());
			Marshaller m = content.createMarshaller();
			StringWriter sw = new StringWriter();
			m.marshal(obj, sw);
			return sw.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}


6.3.3 xml2java


实现对XML转换成JaveBean的实现过程。

public static Object xml2java(String xml, Class clazz) {
		try {
			JAXBContext content = JAXBContext.newInstance(clazz);
			Unmarshaller m = content.createUnmarshaller();
			StringReader sr = new StringReader(xml);
			Object t = m.unmarshal(sr);
			return t;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}


6.4 API说明


Jaxb相关的重要的Class和Interfce。

参考文档:

http://man.lupaworld.com/content/develop/JDK_6.0_API_html_zh_CN/html/zh_CN/api/javax/xml/bind/annotation/package-summary.html


6.4.1 JAXContent


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


6.4.2 Marshaller


Java对象序列化为XML数据。


6.4.3 Unmarshaller


XML数据反序列化为Java对象。


6.5 常用场景


6.5.1 数组或者List属性XML绑定


JaxbList或者数组是需要手动处理,不然打印出来XML格式不是我们需要的。

对上面报文处理,可以选择这么处理:

但是,这样处理与 smooks存在不兼容的问题,考虑到xmlbind平滑性,建议使用:

新增包含List的类:

在类对象中引用包含list的类属性


6.5.2 Map属性XML绑定


Jaxb默认对Map进行处理,可能也不是我们需要格式。

这个是带Map属性的JavaBean,但是最终结果展现不是我们需要的。

如果学会了对象属性进行适配器处理就可以解决此类问题。


6.5.3 Date属性XML绑定(适配器)


jaxbjava.uitl.Date进行处理,转换时间不是中文格式,因为java.util.DatetoString()默认是西方格式。这种风格不适合中国风,也不好认识。

    下面是Date打印:

    2011-09-01T00:00:00-03:00

    而我们需要的是

    2011-09-01 00::00:03

    这时候处理如下:

    


6.5.4 排除属性XML绑定


JavaBean的一些属性有时候是不需要对外进行xml绑定,这时候,我们该怎么处理呢?在该字段前面进行注解@XmlTransient,表示不行对字段进行xml转换。


6.6 优化方案


往往高并发系统对吞吐量要求比较要的,所以,很多XmlBind技术都必须针对不同情况进行相应处理。而Jaxb当中, JAXBContext是属于线程安全的,但是Marshaller, Unmarshaller以及Validato都是非线程安全的。

针对JAXBContext属于线程安全的情况下,实现单例虽然有益于性能提高,但是高并发情况下,更容易出现问题。这种情况下,可以采取对象池来解决

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!