使用 xfire 快速发布 WebService
发布时间:2020-12-17 02:54:15 所属栏目:安全 来源:网络整理
导读:?在经历过早年?Delphi,?C++,?Java?等不成熟环境中开发?WebService?的折磨之后,接触?ASP.NET?的最大感触,就是?WebService?的开发门槛被大大降低了。无需对?SOAP?或基本架构有任何了解,仅需简单的定义几个?Attribute?即可,所有的?dirty?work?都由?ASP.NET?
?在经历过早年?Delphi,?C++,?Java?等不成熟环境中开发?WebService?的折磨之后,接触?ASP.NET?的最大感触,就是?WebService?的开发门槛被大大降低了。无需对?SOAP?或基本架构有任何了解,仅需简单的定义几个?Attribute?即可,所有的?dirty?work?都由?ASP.NET?在后台自动完成。例如:
??????而这一巨大的生产力进步,现在开始在?Java?领域也可直接享用。例如:
??????在项目搭建时完成一次性的配置之后,我们绝大多数的工作就是定义?WebService?接口,设定?WebService?的发布方式。然后就是实现此接口并放入?spring?中进行管理,例如:
??????这一神奇效果的幕后英雄就是?codehaus?最新发布的? xfire?1.0?SOAP?框架。 ??????与?Axis?等现有实现相比,xfire?的最大优点就是改用?StAX?基于流的?XML?分析引擎,加上其?SOAP?协议栈实现上的精巧设计,能够带来比?Axis?快?2-5?倍的性能提升。具体的性能评测数据,可以参考? ?一些第三方评测结果?。 ??????而在功能上?xfire?也毫不逊色,其?Features?&?Goals?里面充满了各种?big?words。 * Support for important Web Service standards - SOAP,WSDL,WS-I Basic Profile,WS-Addressing,WS-Security,etc. * High performance SOAP Stack * Pluggable bindings POJOs,XMLBeans,JAXB 1.1,JAXB 2.0,and Castor support * JSR 181 API to configure services via Java 5 and 1.4 (Commons attributes JSR 181 syntax) * Support for many different transports - HTTP,JMS,XMPP,In-JVM,etc. * Embeddable and Intuitive API * Spring,Pico,Plexus,and Loom support. * JBI Support * Client and server stub generation * JAX-WS early access support ??????与?Axis,?Glue?以及?ActiveSOAP??的详细功能对比,可以参考? Stack?Comparison?文档。 ??????下面先就?xfire?基础架构以及与?spring?集成的基本情况大概做一个简单介绍,回头有时间再整一个?xfire?与?axis?实现架构的横向对比。 ??????与?axis?很相似?xfire?在架构上也可以大概分为?Service,?Transport?和?Invoker?三个层面。 ??????Service?层是?xfire?架构的静态基础,负责完成对服务的注册及其管理。核心的?ServiceRegistry?接口完成对服务自身的生命期管理,如注册/注销/获取等等;而?ServiceFactory?接口则负责从具体的?POJO?类型,生成实现??Service?接口的可被管理的服务代理。 ??????Transport?层则是?xfire?的外部?IO?处理系统。由?TransportManager?接口对具体的?Transport?接口实现进行管理,默认提供了基于?pipe?的?LocalTransport?和基于?Http?协议的?SoapHttpTransport。理论上可以任意进行扩展,例如?xfire?发布包中还提供了基于?JMS?和?XMPP?的实现。 ??????Invoker?则是?xfire?的动态调用层,负责在?Transport?层接受到请求后,解析内容、调用合适服务并最终返回?SOAP?封包给调用者。运行时?Invoker?负责维系?Service?和?Transport?之间的联系。 ??????因此一个服务的生成和注册往往类似如下代码:
??????最基本的?XFire?接口,实际上就是?getServiceRegistry()?和?getTransportManager()?的封装。 ??????xfire?中另一块核心的思想,就是其灵活而强大的?binding?机制,负责完成?Java?类型与?SOAP?消息的双向转换。xfire?仅仅内建就支持?POJO(Aegis),?Castor,?JAXB?1.1,?JAXB?2.0?和?XMLBeans?多种模式,你可以根据需求选择从全自动?POJO?生成,到全手工?xsd?文件定义的不同方式。 ??????而对使用?spring?环境的开发者来说,要提供上述这一系列支持,只需要直接将?xfire-spring?工程中的?fire.xml?文件包括到?applicationContext.xml?中,即可直接获得完整的?xfire?架构。
??????不过相比于通过?xml?文件定义服务来说,我更倾向于直接用?Annotation?方式在代码级完成定义。xfire-annotation?提供了对?Java?5?Annotation?和?apache?common-attribute?的完整支持。例如上述例子中在?javadoc?里定义的?@@?标签,就是?用于使用?xdoclet?生成?common-attribute?支持的。 ??????因为?common-attribute?并非编译器一级提供支持,因此要在编译之前增加一道处理过程。个人推荐直接使用?maven?进行管理,当然也可以在?ant?中直接配置?task。maven?1.x?的具体配置方式如下:
??????增加了以上配置后,在?maven?编译时,会自动增加一个?common-attribute?支持文件的编译过程,并在?target/commons-attributes?下生成类似?ServerVariables$__attributeRepository.java?的文件,以存储?@@?标签中指定的?Metadata。在?eclipse?等?IDE?中,我们可以直接把这些目录添加为源码目录。 ??????而在为了使用?common-attribute?定义的元信息,xfire?提供了?Jsr181HandlerMapping?来自动完成服务映射支持。
??????因为?xfire?同时需要支持?Java?5?模式和?common-attribute?模式的元信息,所以对元信息的获取被封装到?annotations.commons.CommonsWebAttributes?和?annotations.jsr181.Jsr181WebAnnotations?中,以便根据实际使用进行配置。而?xfire?和?xfire.typeMappingRegistry?则是引用前面提到的?xfire.xml?中定义的基础接口和类型映射支持。 ??????Jsr181HandlerMapping?是从?spring?提供的?ApplicationObjectSupport?上基础出来的,它实现了?ApplicationContextAware?接口,因此会在?bean?定义被加载完成后,调用其?setApplicationContext?方法,并进而调用其?initApplicationContext?方法完成初始化。 ??????Jsr181HandlerMapping.initApplicationContext?方法中,会遍历当前?ApplicationContext?的所有父容器,调用?processBeans?方法处理器其?bean?定义。而在?processBeans?中针对每个?bean,检查其是否为?singleton?的非抽象对象,且定义了?WebService?Annotation;如果是则构造?bean?并以前面提到的方式进行注册。 值得注意的是,xfire?1.0?乃至最新?CVS?版本,在这块的实现都有一个严重?bug,没有对?abstract?bean?进行处理。其代码中直接用?beanFactory.getBean(beanNames[i])?试图获取实例,如果?bean?是?singleton?的?abstract?模式,则会导致?spring?抛出异常。可以将其检测代码改成如下方式:
??????此?bug?及修复代码已提交到?xfire?的?JIRA?上,待进一步确认。 ??????而在具体对?bean?是否定义服务的判断上,xfire?1.0?中的支持实际上也是很不完整的。象最上面例子中,由?ServerVariables?定义服务接口,ServerVariablesImpl?中实现服务的方式,直接在?xfire?下是无法使用的。关键原因在于?xfire-annotations?工程在定义?WebService?等?annotation?时,没有指定其可继承性。 ??????改进方法也很简单,在?org.codehaus.xfire.annotations.commons?包的?WebService,?WebMethod,?WebResult,?WebParam?等?annotation?定义中,类一级增加一个?@@org.apache.commons.attributes.Inheritable()?标签即可。common-attribute?在判断是否存在某个?annotation?时,会自动将具有?Inheritable?属性的自定义属性,继承到其所有子类。这样一来就可以很完美的解决通过接口定义服务的问题。此改进也已提交到?xfire?的?JIRA?上,待进一步确认。 ??????完成了这些基础性工作后,剩下的任务就非常简单了。根据?xfire?的? Servlet?Setup?文档,在?web.xml?中增加相关?servlet?的定义,接管?/service/**?或其它?URL。
??????然后就可以通过? ??????完整的?xfire?支持?bean?配置大致如下:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |