1. 如何监测SOAP请求和响应流
之前我们做的演示程序都很简单,方法的参数和返回值都是简单类型的数据,但是在实际
应用过程中往往没有这么简单.在使用面向对象的编程语言时,我们会希望数据类型可是
某个对象,比如我们提供一个接口用来查询城市信息,那么我们希望接口的参数是一个城
市信息对象,这个信息对象封装了一条城市信息的所需要的查询内容包括名称,地区
邮编,区号,人口。面积信息内容等等,如果我们把每个内容都做成一个参数,那这个接口的参数可能会非常的多。因此封装成对象是很有必要的。
在使用Axis来编写Web服务时对复杂类型数据的处理同样也是非常简单。Axis要求复
杂类型对象的编写必须符合JavaBean的规范,简单的说就是对象的属性是通过
getter/setter方法来访问的。来看看下面这个简单的例子所输出的WSDL信息有何特殊的
地方。(我们为了方便使用JbuilderX来快速的开发)准备以下文件.
CityInfo.java
package com.yang;
public class CityInfo {
//地区城市名称 private String cityName; //区号 private String zone; //邮编 private String post; // 行政区 private String district; //人口 private String populace; //面积 private String area;
public String getArea() { return area; }
public String getPopulace() { return populace; }
public String getDistrict() { return district; }
public String getPost() { return post; }
public String getZone() { return zone; }
public void setCityName(String cityName) { this.cityName = cityName; }
public void setArea(String area) { this.area = area; }
public void setPopulace(String populace) { this.populace = populace; }
public void setDistrict(String district) { this.district = district; }
public void setPost(String post) { this.post = post; }
public void setZone(String zone) { this.zone = zone; }
public String getCityName() { return cityName; } } |
DisposeQueryCity.java
package com.yang;
public class DisposeQueryCity {
private String mess = null; private CityInfo cityInfo = null;
public void setCityInfo(CityInfo cityInfo) { this.cityInfo = cityInfo; }
public void setMess(String mess) { this.mess = mess; }
public CityInfo getCityInfo() { return cityInfo; }
public String getMess() { return mess; }
} |
QueryCity.java
package com.yang;
public class QueryCity {
public DisposeQueryCity getQueryCity(CityInfo cityInfo) { CityInfo newCityInfo = new CityInfo(); DisposeQueryCity disposeQueryCity = new DisposeQueryCity(); if (cityInfo.getPost() == null || cityInfo.getPost().equals("")) { disposeQueryCity.setMess("你输入的邮编没有对应的城市!"); disposeQueryCity.setCityInfo(null); } else { if (cityInfo.getPost().equals("362400")) { newCityInfo.setCityName("安溪县(凤城镇)"); newCityInfo.setArea("2983平方千米"); newCityInfo.setDistrict("福建省"); newCityInfo.setZone("0595"); newCityInfo.setPopulace("105万人"); disposeQueryCity.setMess("你输入的邮编对应的城市信息为:"); disposeQueryCity.setCityInfo(newCityInfo); } else if (cityInfo.getPost().equals("350007")) { newCityInfo.setCityName("仓山区"); newCityInfo.setArea("139平方千米"); newCityInfo.setDistrict("福建省"); newCityInfo.setZone("0591"); newCityInfo.setPopulace("35万人"); disposeQueryCity.setMess("你输入的邮编对应的城市信息为:"); disposeQueryCity.setCityInfo(newCityInfo);
} else if (cityInfo.getPost().equals("350001")) { newCityInfo.setCityName("福州市"); newCityInfo.setArea("12154平方千米"); newCityInfo.setDistrict("福建省"); newCityInfo.setZone("0591"); newCityInfo.setPopulace("589万人"); } else if (cityInfo.getPost().equals("361012")) { newCityInfo.setCityName("厦门市"); newCityInfo.setArea("1638平方千米"); newCityInfo.setDistrict("福建省"); newCityInfo.setZone("0592"); newCityInfo.setPopulace("131万人"); disposeQueryCity.setMess("你输入的邮编对应的城市信息为:"); disposeQueryCity.setCityInfo(newCityInfo); } } return disposeQueryCity; } } |
在第九章基础上新建以上JAVA文件。
在Project栏中打开axis [Apache Axis tookit]
在Web Services Designer 栏目在点击Create ServiceàJava Service
点击新建Java Service修改Disply Name为CityService
选择Class or interface com.yang.QueryCity
编译项目
产生如下文件
QueryCity.wsdl
CityInfo_Helper.java
CityInfo.java
DisposeQueryCity_Helper.java
DisposeQueryCity.java
QueryCity.java
QueryCityService.java
QueryCityServiceLocator.java
QueryCityServiceTestCase.java
QueryCitySoapBindingStub.java
我们首先看看QueryCity.wsdl有什么变化
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="http://yang.com" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://yang.com" xmlns:intf="http://yang.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <wsdl:types> <schema targetNamespace="http://yang.com" xmlns="http://www.w3.org/2001/XMLSchema"> <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/> <complexType name="CityInfo"> <sequence> <element name="area" nillable="true" type="xsd:string"/> <element name="cityName" nillable="true" type="xsd:string"/> <element name="district" nillable="true" type="xsd:string"/> <element name="populace" nillable="true" type="xsd:string"/> <element name="post" nillable="true" type="xsd:string"/> <element name="zone" nillable="true" type="xsd:string"/> </sequence> </complexType> <complexType name="DisposeQueryCity"> <sequence> <element name="cityInfo" nillable="true" type="impl:CityInfo"/> <element name="mess" nillable="true" type="xsd:string"/> </sequence> </complexType> </schema> </wsdl:types>
<wsdl:message name="getQueryCityRequest">
<wsdl:part name="cityInfo" type="impl:CityInfo"/>
</wsdl:message>
<wsdl:message name="getQueryCityResponse">
<wsdl:part name="getQueryCityReturn" type="impl:DisposeQueryCity"/>
</wsdl:message>
<wsdl:portType name="QueryCity">
<wsdl:operation name="getQueryCity" parameterOrder="cityInfo">
<wsdl:input message="impl:getQueryCityRequest" name="getQueryCityRequest"/>
<wsdl:output message="impl:getQueryCityResponse" name="getQueryCityResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="QueryCitySoapBinding" type="impl:QueryCity">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getQueryCity">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getQueryCityRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://yang.com" use="encoded"/>
</wsdl:input>
<wsdl:output name="getQueryCityResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://yang.com" use="encoded"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="QueryCityService">
<wsdl:port binding="impl:QueryCitySoapBinding" name="QueryCity">
<wsdlsoap:address location="http://localhost:8080/axis/services/QueryCity"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions> |
红色的部分有明显的变化,比较以前的Hello.wsdl了解一下就可以明白有什么变化了.
这里定义了两个类型CityInfo和DisposeQueryCity,就是我们接口的参数类型以及返回
值的类型。
在Project栏中打开axis àModule directoryàWEB-INFàserver-conig.wsdd
查看和以前有什么变化
<?xml version="1.0" encoding="UTF-8"?> <deployment name="defaultClientConfig" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns:handler="http://xml.apache.org/axis/wsdd/providers/handler" xmlns="http://xml.apache.org/axis/wsdd/"> <globalConfiguration name="GlobalConfiguration1" type="" regenerateElement="false"> <requestFlow name="RequestFlow1" type="" regenerateElement="false"> <handler name="Handler1" type="java:org.apache.axis.handlers.JWSHandler" regenerateElement="false"> <parameter name="scope" value="session" regenerateElement="false"/> </handler> <handler name="Handler2" type="java:org.apache.axis.handlers.JWSHandler" regenerateElement="false"> <parameter name="scope" value="request" regenerateElement="false"/> <parameter name="extension" value=".jwr" regenerateElement="false"/> </handler> </requestFlow> </globalConfiguration> <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper" regenerateElement="false"/> <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder" regenerateElement="false"/> <handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler" regenerateElement="false"/> <transport name="http" type="" regenerateElement="false"> <requestFlow name="RequestFlow1" type="" regenerateElement="false"> <handler name="Handler1" type="URLMapper" regenerateElement="false"/> <handler name="Handler2" type="java:org.apache.axis.handlers.http.HTTPAuthHandler" regenerateElement="false"/> </requestFlow> </transport> <transport name="local" type="" regenerateElement="false"> <responseFlow name="ResponseFlow1" type="" regenerateElement="false"> <handler name="Handler1" type="LocalResponder" regenerateElement="false"/> </responseFlow> </transport> <service name="AdminService" type="" regenerateElement="false" provider="java:MSG"> <parameter name="allowedMethods" value="AdminService" regenerateElement="false"/> <parameter name="enableRemoteAdmin" value="false" regenerateElement="false"/> <parameter name="className" value="org.apache.axis.utils.Admin" regenerateElement="false"/> <namespace>http://xml.apache.org/axis/wsdd/</namespace> </service> <service name="Version" type="" regenerateElement="false" provider="java:RPC"> <parameter name="allowedMethods" value="getVersion" regenerateElement="false"/> <parameter name="className" value="org.apache.axis.Version" regenerateElement="false"/> </service> <service name="Hello" type="" regenerateElement="true" provider="java:RPC" style="rpc" use="encoded"> <parameter name="scope" value="Request" regenerateElement="false"/> <parameter name="className" value="axis.Hello" regenerateElement="false"/> <parameter name="allowedMethods" value="*" regenerateElement="false"/> </service> <service name="QueryCity" type="" regenerateElement="true" provider="java:RPC" style="rpc" use="encoded"> <parameter name="scope" value="Request" regenerateElement="false"/> <parameter name="className" value="com.yang.QueryCity" regenerateElement="false"/> <parameter name="allowedMethods" value="*" regenerateElement="false"/> <typeMapping encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns1:CityInfo" languageSpecificType="java:com.yang.CityInfo" serializer="org.apache.axis.encoding.ser.BeanSerializerFactory" deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" name="CityInfo" regenerateElement="true" xmlns:ns1="http://yang.com"/> <typeMapping encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns2:DisposeQueryCity" languageSpecificType="java:com.yang.DisposeQueryCity" serializer="org.apache.axis.encoding.ser.BeanSerializerFactory" deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" name="DisposeQueryCity" regenerateElement="true" xmlns:ns2="http://yang.com"/> </service> </deployment> |
红色和绿色就是变化的部分,绿色部分定义了方法的参数以及返回值。
CityInfo_Helper.java,CityInfo.java,DisposeQueryCity_Helper.java,DisposeQueryCity.java
这些JAVA文件添加了很多方法例如getTypeDesc、getSerializer、getDeserializer等等。
现在你就可以随便写个小程序测试一下了,我们就不在累赘了。
CityClient.java
package com.yang.generated;
import java.rmi.RemoteException;
public class CityClient { public static void main(String args[]) throws RemoteException { QueryCitySoapBindingStub binding = null; try { binding = (QueryCitySoapBindingStub) new QueryCityServiceLocator().getQueryCity(); } catch (javax.xml.rpc.ServiceException jre) { System.out.println(jre.toString()); }
DisposeQueryCity value = null; CityInfo cityInfo = new CityInfo(); cityInfo.setPost("361012"); value = binding.getQueryCity(cityInfo); if (value.getCityInfo() == null) { System.out.println(value.getMess()); } else { System.out.println(value.getMess()); System.out.println("地 区:" + value.getCityInfo().getCityName()); System.out.println("面 积:" + value.getCityInfo().getArea()); System.out.println("名 称:" + value.getCityInfo().getDistrict()); System.out.println("区 号:" + value.getCityInfo().getZone()); System.out.println("人 口:" + value.getCityInfo().getPopulace());
} } } |
运行Web Run Using "Web Services Server"
在Project栏目中运行CityClient
Messages框输出你信息:
输入的邮编对应的城市信息为:
地 区:厦门市
面 积:1638平方千米
名 称:福建省
区 号:0592
人 口:131万人