加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

使用 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?在后台自动完成。例如:
1

[?WebService(Description = " Common?Server?Variables " ,Namespace = " http://flier.yeah.net/ " )]
2

public ? class ?ServerVariables:?WebService? {
3


4


5

??[?WebMethod(Description
="Obtains?the?Server?Computer?Name",EnableSession=false)]
6

??
public?string?GetMachineName()?{
7

?????
return?Server.MachineName;
8

??}
???
9

}

??????而这一巨大的生产力进步,现在开始在?Java?领域也可直接享用。例如:
?1

/**
?2

?*?Common?Server?Variables
?3

?*?
?4

?*?@@WebService(name?=?"ServerVariables",?serviceName?=?"ServerVariables",?targetNamespace?=?"
http://flier.yeah.net/")
?5

?*?@@SOAPBinding(style?=?SOAPBindingAnnotation.STYLE_RPC)
?6

?
*/

?7

public ? interface ?ServerVariables
?8

{
?9

??
/**
10

???*?@@WebMethod(operationName?=?"GetMachineName",?action="urn:GetMachineName")
11

???*?@@.return?WebResult("machineName")
12

???
*/

13

??string?GetMachineName();
14

}

??????在项目搭建时完成一次性的配置之后,我们绝大多数的工作就是定义?WebService?接口,设定?WebService?的发布方式。然后就是实现此接口并放入?spring?中进行管理,例如:
1

< bean? id ="serverVariables" ?class ="net.yeah.flier.ws.impl.ServerVariablesImpl" ?singleton ="true" >

??????这一神奇效果的幕后英雄就是?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?之间的联系。
??????因此一个服务的生成和注册往往类似如下代码:
1

Service?endpoint? = ?serviceFactory.create(clazz);? // ?根据具体类型创建服务
2

xFire.getServiceRegistry().register(endpoint);????? // ?向服务管理注册服务
3

endpoint.setInvoker( new ?BeanInvoker(bean));????????????? // ?设定服务调用模式


??????最基本的?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?架构。
1

< import? resource ="classpath:/org/codehaus/xfire/spring/xfire.xml" />


??????不过相比于通过?xml?文件定义服务来说,我更倾向于直接用?Annotation?方式在代码级完成定义。xfire-annotation?提供了对?Java?5?Annotation?和?apache?common-attribute?的完整支持。例如上述例子中在?javadoc?里定义的?@@?标签,就是?用于使用?xdoclet?生成?common-attribute?支持的。
??????因为?common-attribute?并非编译器一级提供支持,因此要在编译之前增加一道处理过程。个人推荐直接使用?maven?进行管理,当然也可以在?ant?中直接配置?task。maven?1.x?的具体配置方式如下:
#?
#?project.properties?for?maven?1.x
#
org.apache.commons.attributes.enable=true
org.apache.commons.attributes.index.enable=true
org.apache.commons.attributes.attributepackages=org.codehaus.xfire.annotations.commons;org.codehaus.xfire.annotations.commons.soap;org.codehaus.xfire.annotations.soap
??????其中?org.apache.commons.attributes.enable?负责启用?maven?的?common-attribute?支持;org.apache.commons.attributes.index.enable?启用索引模式,生成时会自动产生一个索引文件?META-INF/attrs.index;org.apache.commons.attributes.attributepackages?则是预定义可能用到的?annotations?的包名称,以便直接用?WebService?这样的简短名字。
??????增加了以上配置后,在?maven?编译时,会自动增加一个?common-attribute?支持文件的编译过程,并在?target/commons-attributes?下生成类似?ServerVariables$__attributeRepository.java?的文件,以存储?@@?标签中指定的?Metadata。在?eclipse?等?IDE?中,我们可以直接把这些目录添加为源码目录。

??????而在为了使用?common-attribute?定义的元信息,xfire?提供了?Jsr181HandlerMapping?来自动完成服务映射支持。
?1

< bean? id ="webAnnotations" ?class ="org.codehaus.xfire.annotations.commons.CommonsWebAttributes" />
?2

< bean? id ="handlerMapping" ?class ="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping" >
?3

????
< property? name ="typeMappingRegistry" >
?4

????????
< ref? bean ="xfire.typeMappingRegistry" />
?5

????
</ property >
?6

????
< property? name ="xfire" >
?7

????????
< ref? bean ="xfire" />
?8

????
</ property >
?9

????
< property? name ="webAnnotations" >
10

????????
< ref? bean ="webAnnotations" />
11

????
</ property >
12

</ bean >

??????因为?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?抛出异常。可以将其检测代码改成如下方式:
?1

public ? class ?Jsr181HandlerMapping? extends ?AbstractUrlHandlerMapping
?2

{
?3

????
private?void?processBeans(ApplicationContext?beanFactory,?AnnotationServiceFactory?serviceFactory)
?4

????
{
?5

????????String[]?beanNames?
=?beanFactory.getBeanDefinitionNames();
?6

????????
?7

????????ConfigurableApplicationContext?ctxt?
=?(ConfigurableApplicationContext)?beanFactory;
?8


?9

????????
//?Take?any?bean?name?or?alias?that?has?a?web?service?annotation
10

????????for?(int?i?=?0;?i?<?beanNames.length;?i++)
11

????????
{
12

????????????BeanDefinition?def?
=?ctxt.getBeanFactory().getBeanDefinition(beanNames[i]);
13

????????????
14

????????????
if?(!def.isSingleton()?||?def.isAbstract())?continue;
15

????????????
16

????????????
//


17

????????}

18

????}
????
19

}
????

??????此?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。
?1

?? < servlet >
?2

????
< servlet-name > XFire </ servlet-name >
?3

????
< display-name > XFire?Servlet </ display-name >
?4

????
< servlet-class >
?5

????????org.codehaus.xfire.transport.http.XFireConfigurableServlet
?6

????
</ servlet-class >
?7

????
< init-param >
?8

??????
< param-name > config </ param-name >
?9

??????
< param-value > services.xml </ param-value >
10

????
</ init-param >
11

??
</ servlet >
12


13

??
< servlet-mapping >
14

????
< servlet-name > XFire </ servlet-name >
15

????
< url-pattern > /servlet/XFireServlet/* </ url-pattern >
16

??
</ servlet-mapping >
17


18

??
< servlet-mapping >
19

????
< servlet-name > XFire </ servlet-name >
20

????
< url-pattern > /services/* </ url-pattern >
21

??
</ servlet-mapping >

??????然后就可以通过?

http://localhost:8080/xfire/services/WeatherService?wsdl ?类似的方式访问?wsdl?或调用?WebService?了。详细的配置请参考?xfire?相关文档。
??????完整的?xfire?支持?bean?配置大致如下:
?1

<? xml?version="1.0"?encoding="UTF-8" ?>
?2

<! DOCTYPE?beans?PUBLIC?"-//SPRING//DTD?BEAN//EN"?"http://www.springframework.org/dtd/spring-beans.dtd" >
?3

<!-- ?applicationContext-xfire.xml? -->
?4

< beans >
?5

????
< import? resource ="classpath:/org/codehaus/xfire/spring/xfire.xml" />
?6

????
?7

????
< bean? id ="webAnnotations" ?class ="org.codehaus.xfire.annotations.commons.CommonsWebAttributes" />
?8

????
< bean? id ="handlerMapping" ?class ="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping" >
?9

????????
< property? name ="typeMappingRegistry" >
10

????????????
< ref? bean ="xfire.typeMappingRegistry" />
11

????????
</ property >
12

????????
< property? name ="xfire" >
13

????????????
< ref? bean ="xfire" />
14

????????
</ property >
15

????????
< property? name ="webAnnotations" >
16

????????????
< ref? bean ="webAnnotations" />
17

????????
</ property >
18

????
</ bean >
19

????
20

????
< bean? class ="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" >
21

????????
< property? name ="urlMap" >
22

????????????
< map >
23

????????????????
< entry? key ="/" >
24

????????????????????
< ref? bean ="handlerMapping" />
25

????????????????
</ entry >
26

????????????
</ map >
27

????????
</ property >
28

????
</ bean >
29

</ beans >
??????如果需要使用?abstract?bean?的话,可以按前面所说修改?Jsr181HandlerMapping,并重新编译?xfire-spring?工程;如果需要提供接口定义服务的支持,可以按前面所说修改?WebService?等,并重现编译?xfire-annotation?工程。 ? ?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读