首页 > 代码库 > .net/java调用NuSOAP构建的Web服务

.net/java调用NuSOAP构建的Web服务

此文主要解决php下的web服务接受和返回复杂类型(自定义类型)该如何构建以及其他程序客户端如何来调用。

第一步:用NuSOAP组件来构建基于php的webservice

下载NuSOAP组件,在创建基于php的webservice时需要引用,代码如下,很简单直观,有注释就不多解释了:

<?php
 require_once (‘lib/nusoap.php‘);
 // 返回的是一个数组
 function adduser ($userName, $userAge, $birthday, $higher) {
  $temp [‘userName‘] = $userName;
  $temp [‘userAge‘] = $userAge;
  $temp [‘birthday‘] = $birthday;
  $temp [‘higher‘] = $higher;
  return $temp;
 }

 function validate($userName)
 {
  if ($userName == "helloworld") {
   return  1;
  }
  else
  {
   return  0;
  }
 }


 $soap = new soap_server ();
 // 避免乱码
 $soap->soap_defencoding = ‘UTF-8‘;
 $soap->decode_utf8 = false;
 $soap->xml_encoding = ‘UTF-8‘;
 $soap->configureWSDL ( ‘Demowsdl‘, ‘urn:Demowsdl‘ );
 $soap->wsdl->schemaTargetNamespace = ‘urn:Demowsdl‘;
 
 // 下面是设置一个返回的数组类型
 // 参数一,为你自己命名的数据类型
 // 参数二,混合类型,不用管
 // 参数三,为结构体,或者数组(array)
 // 参数四,按照什么排序,有三个选择all(全部)|sequence(次序)|choice(选择)
 // 参数五,基本约束
 // 注意:上面5个我们不用改变
 // 参数6,最重要的参数,也就是我们返回的类型想对应
 // 返回数组下标 =>array(‘name‘=>"数组下标",‘type‘=>"xsd:对应的类型")
 // 类型基本包括 string,int, date,boolean 这几种形式
 $soap->wsdl->addComplexType ( ‘userInfo‘, ‘complexType‘, ‘struct‘, ‘all‘, ‘‘, array (
   ‘userName‘ => array (
     ‘name‘ => ‘userName‘,
     ‘type‘ => ‘xsd:string‘
   ),
   ‘userAge‘ => array (
     ‘name‘ => ‘userAge‘,
     ‘type‘ => ‘xsd:int‘
   )
   ,
   ‘birthday‘ => array (
     ‘name‘ => ‘birthday‘,
     ‘type‘ => ‘xsd:date‘
   )
   ,
   ‘higher‘ => array (
     ‘name‘ => ‘higher‘,
     ‘type‘ => ‘xsd:boolean‘
   )
 ) );
 
 // 这里是注册函数
 // 参数一,函数名
 // 参数二,是这个函数接受的参数,注意指定类型
 // 参数三,为返回的值,不一定名字非叫return,叫其他的也可以,注意返回的类型,
 // 我这里是返回我自己定义的类型 tns:userInfo 如果为基本的类型为 xsd:string 这个样子
 // 其他的参数,只要统一就可以了,尤其是名字空间跟 soapaction
 $soap->register (‘adduser‘,
     array (
       ‘userName‘ => ‘xsd:string‘,
       ‘userAge‘ => ‘xsd:int‘,
       ‘birthday‘ => ‘xsd:date‘,
       ‘higher‘ => ‘xsd:boolean‘
     ),
     array (
       ‘return‘ => ‘tns:userInfo‘
     ),
     ‘urn:Demowsdl‘,
     ‘urn:Demowsdl#adduser‘,
     ‘rpc‘,
     ‘encoded‘,
     ‘添加用户‘ ); 
 
 $soap->register ( ‘validate‘,
     array (
       ‘userName‘ => ‘xsd:string‘
     ), 
     array (
       ‘return‘ => ‘xsd:int‘
     ), 
     ‘urn:Demowsdl‘, 
     ‘urn:Demowsdl#validate‘, 
     ‘rpc‘, 
     ‘encoded‘, 
     ‘验证用户名‘ );

 $soap->service ( $HTTP_RAW_POST_DATA );
?>

我测试环境在本机,对应的web在目录phpweb1下,所以:

对外提供的服务地址即是:http://localhost/phpweb1/mynusoapserver.php

对外提供的wsdl地址即是:http://localhost/phpweb1/mynusoapserver.php?wsdl

以上两个地址在浏览器中能正常访问和显示wsdl描述文件,即为成功!

第二步:.net调用NuSOAP构建的web服务

.net下调用就相当简单了,直接在Visual Studio下引用上述给出的服务地址,取一个命名空间名字,这里取为phpservice,客户端代码如下:

using phpservice;

Demowsdl ws = new Demowsdl();

userInfo info = ws.adduser("张三123", 18, DateTime.Now, false);

int result = ws.validate("helloworld");

第三步:java调用NuSOAP构建的web服务

java调用有好几种方式,比如使用apache的axis组件、使用apache的soap组件、或者直接使用wsdl2java把WSDL文件转成本地类,然后像本地类一样使用,这里我就使用第三种方式演示一下,为了使用wsdl2java命令,我们得先配置一下,去下载Axis2包,然后输入如下命令:

G:\phppackage\axis2-1.6.2\bin>wsdl2java -o c:\  -uri http://localhost/phpweb1/mynusoapserver.php?wsdl

命令执行完毕后,在指定c:\下的目录src\demowsdl中生成了本地客户端代理类,文件分别为:

DemowsdlCallbackHandler.java、DemowsdlStub.java 拷贝到java工程的源文件下(src目录)(带上目录demowsdl),最终的客户端代码为:

package demowsdl;
import java.util.Date;
import demowsdl.DemowsdlStub.AdduserResponse;
import demowsdl.DemowsdlStub.ValidateResponse;
public class TestPhpService {
 public static void main(String[] args) {
  try {
   // 获得Stub实例
   DemowsdlStub s = new DemowsdlStub();
   // 调用第一个方法
   DemowsdlStub.Adduser input_info = new DemowsdlStub.Adduser();
   input_info.setUserName("张三123");
   input_info.setUserAge(18);
   input_info.setBirthday(new Date());
   input_info.setHigher(false);
   // 得到返回值
   AdduserResponse res = s.adduser(input_info);
   DemowsdlStub.UserInfo output_info = res.get_return();
   // 调用第二个方法
   DemowsdlStub.Validate input_info2 = new DemowsdlStub.Validate();
   input_info2.setUserName("helloworld");
   // 得到返回值
   ValidateResponse res2 = s.validate(input_info2);
   int output_info2 = res2.get_return();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

以上服务端程序和客户端程序均测试通过,完毕!