从客户端除了传递字符串以外还可以传递复杂对象(对象必须序列化了),List,Map,数组和文件。

(1)定义一个对象实现了serializable 接口
package cn.com.chenlly.ssh.webservice.axis;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class Address implements Serializable { //复杂类型的类要序列化
 
 private Integer identifier;
 
 private String address;
 
 private String city;
 
 private String province;
 
 private String country;
 
 private String []array;   //javabean里的复杂类型
 
 private List<Integer> list;(基本类型)
 
 private boolean isExst;
 
 
 //constructor
 public Address(){
 
  list = new ArrayList<Integer>();
 
  list.add(1);
 
  list.add(2);
 
  list.add(3);
 }
 public Integer getIdentifier() {
  return identifier;
 }

public void setIdentifier(Integer identifier) {
  this.identifier = identifier;
 }

public String getAddress() {
  return address;
 }

public void setAddress(String address) {
  this.address = address;
 }

public String getCity() {
  return city;
 }

public void setCity(String city) {
  this.city = city;
 }

public String getProvince() {
  return province;
 }

public void setProvince(String province) {
  this.province = province;
 }

public String getCountry() {
  return country;
 }

public void setCountry(String country) {
  this.country = country;
 }

public String[] getArray() {
  return array;
 }

public void setArray(String[] array) {
  this.array = array;
 }

public List<Integer> getList() {
  return list;
 }

public void setList(List<Integer> list) {
  this.list = list;
 }

public boolean isExst() {
  return isExst;
 }

public void setExst(boolean isExst) {
  this.isExst = isExst;
 }
}

(2)定义server-config.wsdd文件

<deployment xmlns="http://xml.apache.org/axis/wsdd/"
 xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
 <handler name="URLMapper"     //定义了两个handler(非必须),类似于过滤器
  type="java:org.apache.axis.handlers.http.URLMapper" />
 <handler name="wsTestHandler"
  type="java:cn.com.chenlly.ssh.webservice.axis.WSTestServiceHandle">
  <parameter name="status" value="success" />
 </handler>
 <!-- 自定义服务 -->
 <service name="ws" provider="java:RPC">
  <parameter name="className"
   value="cn.com.chenlly.ssh.webservice.axis.WSTestServiceImpl" />
  <parameter name="allowedMethods" value="*" />
  <parameter name="scope" value="request" />
 
  <responseFlow>
   <handler type="wsTestHandler" />    //响应时使用上面的handler

</responseFlow>
  <requestFlow>//请求时使用上面的handler
   <handler type="wsTestHandler" />

</requestFlow>
 
  <beanMapping qname="myNSD:Address"   //复杂类型javabean(用于传送的序列化对象)
   xmlns:myNSD="urn:AddressManager"
   languageSpecificType="java:cn.com.chenlly.ssh.webservice.axis.Address">
  </beanMapping>
 </service>

<transport name="http">
  <requestFlow>
   <handler type="URLMapper" />
  </requestFlow>
 </transport>
</deployment>

//主要是<beanMapping>标签中名字空间和qname写法
第一个你自定义的命名空间和第二个节点本地部分会组成一个新的QName。

生成的WSDL有如下一段
- <schema targetNamespace="urn:AddressManager" xmlns="http://www.w3.org/2001/XMLSchema">
  <import namespace="http://192.168.1.98:8082/SSHProject/services/ws" />
  <import namespace="http://xml.apache.org/xml-soap" />
  <import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
- <complexType name="Address">
- <sequence>
  <element name="address" nillable="true" type="soapenc:string" />
  <element name="array" nillable="true" type="impl:ArrayOf_soapenc_string" />
  <element name="city" nillable="true" type="soapenc:string" />
  <element name="country" nillable="true" type="soapenc:string" />
  <element name="exst" type="xsd:boolean" />
  <element name="identifier" nillable="true" type="soapenc:int" />
  <element name="list" nillable="true" type="impl:ArrayOf_xsd_anyType" />
  <element name="province" nillable="true" type="soapenc:string" />
  </sequence>
  </complexType>
  </schema>
这个新的schema就是把对象序列化以后生成了xml流文件。

(3) webService 服务方法
public Address dealAddress(Address address) {
   System.out.println("service exst:"+address.isExst());
   //客户端对象传递过来设置标志为true
   address.setExst(true);
   return address;
}

(4) 客户端
package cn.com.chenlly.ssh.webservice.axis;

import java.util.ArrayList;
import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;

public class WSTestServiceClient {
 public static void main(String[] args) {
  Service service = new Service();
  try {
   Call call = (Call) service.createCall();
   String url = "http://192.168.1.98:8082/SSHProject/services/ws?wsdl";
   call.setTargetEndpointAddress(new java.net.URL(url));
                        //定义对象
   Address address = new Address();
   address.setIdentifier(1);
   address.setProvince("湖南");
   address.setCity("长沙");
   address.setExst(false);

QName qn = new QName("urn:AddressManager", "Address");//第一个参数名字空间URI,第二个参数本地部分,注意这两部分在server-config.wsdd文件中标签beanMapping配置
   call.registerTypeMapping(Address.class, qn,
     new BeanSerializerFactory(Address.class, qn),//序列化
     new BeanDeserializerFactory(Address.class, qn));
 
   call.setOperationName(new QName(url,"dealAddress"));
 
   call.addParameter("arg0", qn, ParameterMode.IN);//定义一个参数类型,如果是String类型的参数可以不需要这句话
   call.setReturnClass(Address.class);//指定返回类型
 
   Address result = (Address) call.invoke(new Object[]{address});//这里传递给service的是一个对象
   System.out.println(result.isExst());
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}
//在服务器端打印的isExst()方法是false;然后设置address的exst为true;最后又传送到客户端打印的result结果为true

<beanMapping/> 需要说明的是:

1 如果服务中不需要传递对象,是不需要<beanMapping/>对的.而且這里面的对象必须要是符合javaBean模式的对象,最起码要符合get/set方法對.

2 qname xmlns:xx languageSpecificType分別用于指定参数对象的命名空间.用于在客戶端调用.

二、开发service
服务器端的service为普通的java类:com.hnisi.axis.BookOrder

public class BookOrder {
public String getName(String name) {
System.out.println("start execute ...");
return "book name: " + name;
}

public Book setPrice(Book book){
book.setPrice(10);
return book;
}
}

com.hnisi.axis.Book为简单的值对象,包含两个属性name,price。

三、发布service(将会错误)
1、手工修改server-config.wsdd文件(在已有server-config.wsdd文件的情况下)
添加service:

<service name="BookOrder" provider="java:RPC">
<parameter name="allowedMethods" value="*"/>
<parameter name="className" value="com.hnisi.axis.BookOrder"/>
</service>

原因:

由于SOAP中值的类型就是XML Schema中的基本类型,默认只支持简单类型和数组。所以在进行对象传递的过程中,需要进行序列化和反序列化。

Axis为提供了大量的序列化/反序列化器,能够基本满足大部分应用:
1、基本类型,如int、double等,转换成基本对象类型java.lang.Integer、java.lang.Double。
2、常用集合对象的转换
java.util.List ==> java.lang.Object[]
java.util.Vector  ==> java.util.Vector
3、普通JavaBean(简单值对象)的序列化和反序列化
首先,在web service部署端,修改server-config.wsdd文件,在具体的service配置,增加如下代码:
<beanMapping languageSpecificType="java:com.hnisi.axis.Book" qname="ns1:Book"
         xmlns:ns1="urn:BeanService"/>
languageSpecificType属性指定JavaBean类文件位置,qname属性指定JavaBean类的名字。当然,一个service可以绑定多个bean对象。

其次,在客户端,完成对象的注册。
对于调用方法一中,需要新增如下代码以完成注册:
QName qn = new QName("urn:BeanService","Book");
call.registerTypeMapping(Book.class, qn,
new BeanSerializerFactory(Book.class, qn),
                    new BeanDeserializerFactory(Book.class, qn));
而对于调用方法二,重新根据wsdl生成java代码,已完成必要的对象注册过程,CallService中可以直接传递Book对象了。

1)axis1.2内在支持的几种对象类型。
          这几种内在支持的对象包括:
          java基本类型 : int, float,,,,
          基本类型包装类 : Integer, Float, Long...
          还有String, Date, Calendar, BigDecimal, BigInteger, List, Map.
     凡是这些内在支持的对象, 不管他们作为某个Service的input 还是 output, 我们在服务端的axis1.2的WEB-INF/server-config.wsdd的该Service的定义中都不需要加入 <beanMapping>或者是<typeMapping>的声明。

2)简单的javabean对象类型。所有的field都是上面提到的基本类型

由于MyBean是一个自定义的JavaBean对象, 所以在server-config.wsdd中就必须加上<beanMapping ...../>的声明, 让axis知道怎么把request中xml数据deserialize为MyBean对象,又如何把MyBean对象serialize为xml数据作为response.用wtp自动为JavaInputService生成的wsdl中, MyBean是作为一个complexType在wsdl中定义的。

3)复杂一点的JavaBean对象。
        比如JavaBean对象中的一些field又是自定义的JavaBean,  这种情况下, wsdl中生成的complextype会有多个(webservice接口最好不用定义多层的结构),而在wsdd定义的<beanMapping .../>也会有多个, axis1.2支持起来都是易如反掌。

4)java中的数组

在webservice中把List, Map作为service的input, output的做法都是不可行的。至少在jdk1.4的版本中是这样的。

要注意的是,数组参数在server-config.wsdd中需要配置<arrayMapping.../>

似乎List, Map的问题用数组就可以解决了。事实上就是如此。但是还得注意的是:
   javabean里边也不能含有List?. 如果MyBean跟其它某个对象是1:n的关系,那么也只能写成数组的形式,而不能是List的形式

例子:

<service name="StudentInfoService" provider="java:RPC">

<parameter name="className" value="com.kevinGQ.service.axis.service.GetStudentService"/>

<parameter name="allowedMethods" value="*"/>

<beanMapping qname="myNS:Student" xmlns:myNS="urn:StudentInfoService" languageSpecificType="java:com.kevinGQ.service.axis.model.Student"/>

</service>

片断中StudentInfoService是这个web service的名字,在客户端编码的时候需要用到。

<parameter name="className" value="com.kevinGQ.service.axis.service.GetStudentService"/>

中说明了这个服务提供的类,包括package的完整类名。

<parameter name="allowedMethods" value="*"/>中说明这个服务中可供给外部调用的方法有哪些,*表示全部函数,现在也可以把*改成getAStudent.

<beanMapping qname="myNS:Student" xmlns:myNS="urn:StudentInfoService" languageSpecificType="java:com.kevinGQ.service.axis.model.Student"/>中说明对于这个JavaBean的传输需要如何对它进行serializing和de-serializing,说明的目的在于绑定JavaBean的对象类别。注意标签中说明的名字空间。这个标签其实是如下标签的一个简写:

Java代码 

1         <typeMapping qname="myNs:Student" xmlns:ns="urn:StudentInfoService"

2                      languageSpecificType="java: com.kevinGQ.service.axis.model.Student "

3                      serializer="org.apache.axis.encoding.ser.BeanSerializerFactory "

4                      deserializer=" org.apache.axis.encoding.ser.BeanDeserializerFactory "

5                      encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>

特别说明:

A、 如果你调用的方法有返回值,一定要设置返回值的类型。call.setReturnClass

B、 如果你调用的方法有参数,一定要设置参数的类型call.addParameter

C、 记得添加wsdl4j.jar,序列化转换的时候需要用到,否则会出现找不到类型异常

如:

call.addParameter("i", XMLType.XSD_INT, ParameterMode.IN);
 call.setReturnClass(User[].class);

复杂对象类型的WebService高级部分的更多相关文章

  1. 一:Newtonsoft.Json 支持序列化与反序列化的.net 对象类型;

    导航目录: Newtonsoft.Json 概述 一:Newtonsoft.Json 支持序列化与反序列化的.net 对象类型:    二:C#对象.集合.DataTable与Json内容互转示例: ...

  2. 六:python 对象类型详解二:字符串(下)

    一:字符串方法: 方法就是与特定对象相关联在一起的函数.从技术的角度来讲,它们是附属于对象的属性,而这些属性不过是些可调用的函数罢了.Python 首先读取对象方法,然后调用它,传递参数.如果一个方法 ...

  3. Python(二)之对象类型

    本篇记录Python对象类型 开始仍然是先掌握几个查看对象有用的函数,id,type,print 查看对象身份.类型.值:记住以下两个命令id,type 两个对象的比较 以上三个分别是 身份比较.对象 ...

  4. 《Python学习手册 第五版》 -第4章 介绍Python对象类型

    本章的内容主要是介绍了Python的核心对象类型,后续的5.6.7.8.9章针对这些核心类型分别展开详细的说明 本章我认为重要的有几点 1.作者有谈到Python的知识结构,这个我感觉是一个大框架,可 ...

  5. SAP CRM 用户界面对象类型和设计对象

    在CRM中的用户界面对象类型的帮助下,我们可以做这些工作: 进行不同的视图配置 创建动态导航 从设计层控制字段标签.值帮助 控制BOL对象的属性的可视性 从导航栏访问自定义组件 一个用户界面对象类型之 ...

  6. JS 之Blob 对象类型

    原文 http://blog.csdn.net/oscar999/article/details/36373183 什么是Blob? Blob 是什么? 这里说的是一种Javascript的对象类型. ...

  7. Python中的对象类型的初步介绍

    一:介绍 1.为什么使用内置对象 对象类型是语言的一个部分 内置对象构成了每个python程序的核心部分 2.核心数据类型 数字 字符串 列表 字典 元组 文件 集合 其他类型 编程单元类型 与实现相 ...

  8. Java经典实例:进阶版堆栈实现,支持任何对象类型

    支持任何对象类型,有更多的错误检查. package Stack; /** * Created by Frank */ public class MyStack<T> implements ...

  9. JavaScript中判断对象类型方法大全1

    我们知道,JavaScript中检测对象类型的运算符有:typeof.instanceof,还有对象的constructor属性: 1) typeof 运算符 typeof 是一元运算符,返回结果是一 ...

随机推荐

  1. Android 之 沉浸式状态栏及顶部状态栏背景色设置

    现在很多应用都引用了沉浸式状态栏,如QQ,效果下图: 效果很酷炫,其实设置也很简单.但是,需要注意的是,这种效果只能在API19以及以上版本中才能够做到. 方法一: 首先,如果想让界面Activity ...

  2. HDS Truecopy实现原理及项目的选择-诸多案例

    copy from:http://www.eygle.com/archives/2009/05/hds_truecopy_dataguard.html 诸多案例:http://wenku.baidu. ...

  3. 用Android程序打开和关闭输入法

    一.打开输入法窗体: InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Context.INPU ...

  4. 转-ubuntu清理卸载wine的残余项目

    背景:前段时间,装了wine试用了一下,感觉实在没啥意思就卸载了.但是卸载以后发现还有些尾巴碍眼,如打开文件时右键菜单里就会有“使用notepad打开”的选项,虽然没有什么别的问题,但是看着碍眼.所以 ...

  5. CentOS7 vsftp使用ftp客户端登录时不同的用户进入到不同的文件夹方法

    anonymous_enable=NO local_enable=YES write_enable=YES local_umask=777 #anon_upload_enable=YES #anon_ ...

  6. linux C++ 莫名奇异的段错误(segmentation fault),无法调用其他函数

    进来在linux下开发C++项目,遇到了非常奇怪的bug. 项目须要多线程实现,在写好代码后,每当执行到线程函数内部,当内部调用其他函数如printf.fopen等时就会提示段错误(segmentat ...

  7. 面向对象高级——Object类、包装类以及匿名内部类

    Object类  知识点:掌握Object类的作用.掌握Object类中toString().equal()方法的作用 ,掌握Object接收引用数据类型的操作. 假设一个类在定义时没有明白指明继承哪 ...

  8. Servlet路径跳转问题

    Servlet中路径跳转(服务器端跳转)JSP 1.相对路径  注意这里的相对含义,相对于谁而言 经过多次试验总结,servlet相对路径跳转相对于servlet配置的xml路径(或servlet3. ...

  9. Servlet学习(一)

    Servlet的运行过程 Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后: ①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象.如果是,则直 ...

  10. 转 Linux定时执行任务命令at和crontab

    本文介绍在Linux下的两种定时执行任务的方法:at命令,以及crontab服务. (1)at命令 假如我们只是想要让特定任务运行一次,那么,这时候就要用到at监控程序了. 设置at命令很简单,指示定 ...