`

xFire开发webService返回复杂对象

 
阅读更多

XFire开发时,在返回数据类型时遇到了一些麻烦,查到这样一篇文单,非常不错,故收藏之。

翻译: zilong3927 原文地址: http://docs.codehaus.org/display/XFIRE/Mapping+collections

调用 Web Services 时,经常需要返回集合( collection )作为结果,或者接受 collection 型的参数。 SOAP 本身就支持这一点。

但是这一机制的问题在于, java 语言的 collections 是无类型的( untyped . 因此,如果要在 Java 1.4 当中支持 collections 就需要做一些额外的工作。

Java 5 & 范型( Generics

首先而且是推荐的做法是在 JDK5 当中使用范型( generics )。范型能够使你在代码当中为你的 collections 指定类型信息, 从而允许 xfire 自动地推导出 collection 类型,生成正确的 wsdl 等等。

下面示例了如何写这样的一个方法:

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->public Collection < String > getValuesForIds(Collection < Integer > );

Java 1.4 & 集合( Collections

有些情况下并不总能够使用范型( generics . 例如,如果你的部署环境使用 JDK 1.4 或者你想暴露一些遗留的服务,而同时又不打算修改任何代码也不打算进行移植。

对于这样的一些情况而言, 你需要生成一个 xml 映射文件,来指定方法和它们对应的集合类型( collection types .

这个 xml 文件的名字必须是 <className>.aegis.xml 其中 className 是你的服务( service )的接口类( unqualified class )的名字。

下面最好通过一个例子来展示这个 xml 文件的格式。 我们想要展现的服务有这样的一个接口 :

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->public interface MyService1{
StringgetFoo();
CollectiongetCollection();
void setList( int id,java.util.List);
}

既然代码中的 collections 没有指定类型, 我们剧需要生成一个 xml 文件来指定所需要的类型。 这个文件的路径应该和 MyService1.class 在同一个包( package )当中, 并且它的名字应该是 MyService1.aegis.xml

对于这个接口来说,一个最简单的映射文件如下 :

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> < mappings >
< mapping >
< method name ="getCollection" >
< return-type componentType ="java.lang.String" />
</ method >
< method name ="setList" >
< parameter index ="1" componentType ="java.lang.String" />
</ method >
</ mapping >
</ mappings >

注意这个映射文件确切地指定了所需要的信息,不包含任何冗余。 例如, getFoo 方法没有被指定,这是由于它没有包含任何 collections ,因此能够在没有任何映射信息的情况下暴露给使用者。

其次, setCollection 方法没有指定索引为 0 的参数。 这是由于该参数类型为 int ,因此不需要任何映射

如果我们有多个方法,都匹配指定的映射又该怎么办 ? 这种情况下, 映射就对所有匹配的方法均有效。

所以,如果在我们的接口中增加以下的方法:

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->void setList( int id ,java.util.List, boolean persist);

那么现在我们的映射定义对于两个 setList 方法都有作用。这种情况下, 我们不必为额外的参数(译者注:此处指 boolean persist )指定两次映射 . 映射文件就指定了所有那些第二个参数为 List 的方法,并假定 List 中包含的都是 strings

如果我们想让那个具有 3 个参数的方法,其中的 list 不包含 Strings 而是实际上包含 Dates? 这种情况下, 就需要一个更确切的映射来覆盖( override )原先那个更一般的, 所以我们的映射文件需要添加下面这个定义 :

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> < method name ="setList" >
< parameter index ="1" componentType ="java.lang.String" />
< parameter index ="2" class ="boolean" />
</ method >

注意一下类型属性。 现在这个映射将对所有那些第二个参数为 List ,第三个参数为 boolean 型的方法适用。 在我们的接口当中,这个映射唯一地确定了一个特定的方法,使用这个映射就能够解释方法当中的 List 参数。

在优先顺序方面, 更确切的映射总是优先于更一般的。

让我们考虑下面这个复杂一些的例子 :

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->public interface MyService2
{
CollectiongetCollection();
// method1
CollectiongetCollection( int id); // method2
CollectiongetCollection(Stringid); // method3
CollectiongetCollectionForValues( int value,Collectionc); // method4
CollectiongetCollectionForValues(Stringid,Collectionc); // method5
}

映射文件的内容为 :

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> < mappings >
< mapping >
<!-- mapping1 -->
< method name ="getCollection" >
< return-type componentType ="java.lang.Double" />
</ method >
<!-- mapping2 -->
< method name ="getCollection" >
< return-type componentType ="java.lang.Float" />
< parameter index ="0" class ="int" />
</ method >
<!-- mapping3 -->
< method name ="getCollectionForValues" >
< return-type componentType ="java.math.BigDecimal" />
</ method >
<!-- mapping4 -->
< method name ="getCollectionForValues" >
< parameter index ="0" class ="java.lang.String" />
< parameter index ="1" componentType ="java.util.Date" />
</ method >
<!-- mapping5 -->
< method name ="getCollectionForValues" >
< return-type componentType ="java.util.Calendar" />
< parameter index ="0" class ="int" />
< parameter index ="1" componentType ="java.lang.Bit" />
</ method >
</ mapping >
</ mappings >


这个文件的格式是不需要做过多解释的。但有几点还是需要加以说明。

先来看一下第一个映射 (mapping 1) 这个映射指定了所有 getCollection 方法所返回的 collections contain 均包含 java.lang.Doubles 如果没有指定其他的 getCollection 映射, 那么这个映射将对方法 1 2 3 都适用。

但是,第二个映射更加明确地指定了它所适用的方法。即如果 getCollection 方法的第一个参数是 int 型,那么该方法所返回的 collection 包含的是 Float 型。 由于这条规则更加明确,它将为方法 2 覆盖掉第一个映射,这是满足映射约束标准的。

使用以上的规则,不难推导出方法 4 和方法 5 返回的 collections 结果的组件类型( component types )。

Collections on Javabeans

对于使用 collections java beans 来说,语法也是类似的。 例如,比方说我们有一个 Company bean ,包含了一个 List 其中的对象是 employees:

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> public class Company
{
private Collectionemployees;
CollectiongetEmployees(){
return employees;}
public void setEmployees(Collectionemployees){ this .employees = employees};
}

除了可以使用 <method> & <parameter> 元素外, 也可以使用 <property> 元素 :

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> < mappings >
< mapping >
< property componentType ="org.codehaus.xfire.Employee" />
</ mapping >
</ mappings >

Handling Maps

Java Maps 并不能很好地映射到 XML Schema (no pun intended) ,因为 XML Schema 中没有 Map 的概念,客户端也是这样, Maps 被转换成 {key value} 元组的集合。 除了要提供 value 的类型以外,你还必须为 Aegis 提供 key 的类型 :

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> public class GiftService{
MapgetGiftList(){
/* returnsamapofNiceChild=>Present */ }
}

映射文件应该像下面这样 :

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> < mappings >
< mapping >
< method name ="getGiftList" >
< return-type keyType ="org.codehaus.xfire.NiceChild" componentType ="org.codehaus.xfire.Present" >
</ method >
</ mapping >
</ mappings >

这将生成下面的类型 :

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> < xsd:complexType name ="NiceChild2PresentMap" >
< xsd:sequence >
< xsd:element name ="entry" minOccurs ="0" maxOccurs ="unbounded" >
< xsd:complexType >
< xsd:sequence >
< xsd:element name ="key" type ="ns1:NiceChild" minOccurs ="0" maxOccurs ="1" />
< xsd:element name ="value" type ="ns1:Present" minOccurs ="0" maxOccurs ="1" />
</ xsd:sequence >
</ xsd:complexType >
</ xsd:element >
</ xsd:sequence >
</ xsd:complexType >

Collections of Collections of Collections of....

在某些情况下,你可能想要传递 Collections of Collections 。比方说你有一个返回 List of a List of Doubles 的服务 ( 不要问为什么你要做这样一件事情 ...):

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->public class ListService
{
public ListgetListOfListOfDoubles
{
Listl
= new ArrayList();
Listdoubles
= new ArrayList();
doubles.add(
new Double( 1.0 ));
l.add(doubles);
return l;
}
}

要处理这种情况,我们需要引进一个新的 <component> 元素。 下面是一个很好的例子 :

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> < mappings >
< mapping >
< method name ="getListofListofDoubles" >
< return-type componentType ="#someDoubles" />
</ method >
< component name ="someDoubles" class ="java.util.List" componentType ="java.lang.Double" />
</ mapping >
</ mappings >

正像你在这里所看到的,返回类型的 componentType 是一个指向 <component> 的引用,而不是一个类。组件类型 "#someDoubles" 引用到名字为 "someDoubles" <component>

Aegis 将会自动给这些 collections 命名为 ArrayOfDouble ArrayOfArrayOfDouble 你也可以改变这些名字。 要设置你自己的名字, 提供一个 "typeName" 属性即可 :

<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> < mappings >
< mapping >
< method name ="getListofListofDoubles" >
< return-type componentType ="#someDoubles" typeName ="LotsOfDoubles" />
</ method >
< component name ="someDoubles" class ="java.util.List" typeName ="SomeDoubles" componentType ="java.lang.Double" />
</ mapping >
</ mappings >
分享到:
评论

相关推荐

    XFire开发实践记录-包括环境准备与复杂对象的配置方法

    在本文中,我们将探讨XFire框架在开发Web服务中的实践应用,以及如何处理复杂对象的传递。XFire作为MyEclipse 5.5默认的Web服务框架,虽然可能现在不是主流选择,但它提供的IDE支持使得环境配置和开发相对简便。 ...

    XFire令WebService如此简单

    【XFire:让WebService开发变得简单】 XFire是一款强大的Java Web Service框架,它极大地简化了创建和使用Web服务的过程。通过XFire,开发者可以轻松地将普通的Java接口转换为符合WS-I标准的Web服务,无需复杂的...

    相关文档

    1. "xFire开发webService返回复杂对象.doc" - 这份文档很可能是关于如何使用xFire框架创建Web服务,并处理返回的复杂数据结构。xFire是一个开源的Java Web服务框架,它允许开发者将Java对象直接暴露为Web服务。复杂...

    Xfire整合webservice jar包

    通过以上分析,我们可以看出"Xfire整合webservice的所有jar包"是一个涵盖Java Web服务开发、API集成和游戏社区服务开放的复杂项目,涉及到的技术点广泛而深入。理解并熟练掌握这些知识点对于进行类似项目的开发是...

    xfire实现webservice的例子

    Web服务可以接受和返回各种数据类型,包括基本类型、复杂对象、数组和列表等。XFire支持JAXB来自动序列化和反序列化这些数据。例如,如果你的服务需要接收一个自定义的对象,你可以这样做: ```java public class ...

    XFire Webservice 服务器端

    综上所述,XFire Webservice服务器端是一个复杂的系统,涉及到了Web Service的核心概念、安全实践、性能优化等多个方面,对游戏开发者提供了丰富的功能接口,使得游戏能够更好地融入XFire的生态系统。

    webservice xfire 客户端调用实现

    对象传递是XFire的一大特色,它使得复杂的业务对象能够在Web服务之间无缝传递。在传统的Web服务中,通常需要将对象转换为XML再进行传输,而XFire支持直接的对象序列化和反序列化。这意味着你可以直接在方法参数或...

    webservice xfire配置示例

    Web服务(Web Service)是一种基于互联网的、使用标准XML(Extensible Markup ...通过研究这些文件,你可以更好地理解XFire在实际开发中的应用。同时,不要忘记查阅官方文档和社区资源,以获取最新的信息和技术支持。

    xfire实现web service入门实例

    1. **安装和配置Xfire**:首先,你需要下载Xfire的最新版本并将其添加到你的开发环境中,如Eclipse或IntelliJ IDEA。通常,这涉及添加Xfire的JAR文件到项目的类路径中,或者在IDE的构建路径设置中进行配置。 2. **...

    webservice (xfire,axis2)

    Xfire是一个早期的Java WebService框架,它提供了一个轻量级、快速且易于使用的解决方案,使得开发人员可以方便地创建和消费Web服务。Xfire基于Spring框架,使得集成和配置变得更加简单。它支持SOAP、WSDL、UDDI和WS...

    WebService xfire学习报告

    2. **使用XFire开发Web Service** XFire通过简单的API和配置,可以让开发者快速创建和注册Web Service。例如,开发者可以使用如下代码创建和注册服务: ```java ServiceRegistry registry = ...

    xfire的简单实例

    在xfire中,我们无需深入了解这些复杂的概念和协议,因为xfire提供了一种抽象化的开发方式,使得开发者可以专注于业务逻辑,而将底层的通信细节交给框架处理。 【标签】:“xfire webservice” xfire是专门为简化...

    WebService XFire

    【WebService XFire】是基于Java的Web服务框架,它允许开发者快速、轻松地创建和部署SOAP(简单对象访问协议)服务。XFire是Apache CXF的前身,它提供了丰富的API和工具,使得Web服务的开发过程更为简洁。这篇博客...

    webservice开发方式,报文修改

    首先,Web Service的实现框架众多,如AXIS、CXF、JAX-RPC(JAX)、XFire等。这些框架都能根据WSDL(Web Service Description Language)文件自动生成服务端和客户端的代码,使得开发更加便捷。WSDL文件定义了服务的...

    WebService--xfire中对集合的配置和操作

    WebService是Web服务的一种标准协议,它允许不同系统之间的应用程序通过Internet进行通信。XFire是Java平台上的一款开源...理解这些概念对于开发基于XFire的Web服务至关重要,尤其是在处理大量数据或复杂对象结构时。

    springMvc+mybatis+xfire源码

    XFire通过Aegis绑定提供与Java对象的直接映射,简化了Web服务的开发。 在"web_shop"这个压缩包中,很可能包含了某个基于Spring MVC、MyBatis和XFire构建的网上商城项目的源代码。这个项目可能包含了以下组件: 1. ...

    WebService

    通过上述步骤,你就可以使用xFire开发出一个简单的WebService。然而,实际应用中可能需要处理更复杂的业务逻辑和集成更多的Web服务标准。因此,理解WebService的基本原理和xFire的工作方式至关重要,这对于构建高效...

    Java Web Service xFire Demo项目,带所有的包,完美运行

    Java Web服务是应用...此外,它还涵盖了如何处理复杂类型,如实体类和集合类,这些都是Java Web服务开发中的基础技能。这个项目对于初学者来说是一个很好的实践平台,能够帮助他们深入理解Web服务的工作原理和应用。

    xfire客户端需要的jar

    XFire是Apache CXF项目的前身,它最初设计的目标是简化Web服务的开发过程,尤其是对于那些不熟悉SOAP(简单对象访问协议)和WSDL(Web服务描述语言)的开发者。XFire利用了Java的注解(annotations)来定义服务接口...

Global site tag (gtag.js) - Google Analytics