最近用到了cxf的webservice组件,为外部系统提供的接口访问,对接过程中发现外部系统发过来的接口参数,在我这边竟然都是null,于是抓包分析,发现cxf产生的soap报文的格式是这样的:
- <soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
- <soap:Body>
- <ns1:testMethod xmlns:ns1="http://test/" >
- <arg0>2006001 </arg0>
- <arg1>admin</arg1>
- <arg2>admin</arg2>
- <arg3>beijing</arg3>
- </ns1:testMethod>
- </soap:Body>
- </soap:Envelope>
而外部系统发过来的soap报文格式如下:
- <?xml version= "1.0" encoding= "UTF-8" ?>
- <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" >
- <soapenv:Body>
- <ns1:testMethod soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
- xmlns:ns1="http://soap.account.bossIntf.tjb.runway.com" >
- <in0 xsi:type="xsd:string" > 2006001 </in0>
- <in1 xsi:type="xsd:string" >admin</in1>
- <in2 xsi:type="xsd:string" >admin</in2>
- <in3 xsi:type="xsd:string" >beijing</in3>
- </ns1:testMethod >
- </soapenv:Body>
- </soapenv:Envelope>
于是询问外部系统公司人员,使用的是什么组件实现webservice,回答是axis1.4.
接着就是把接口都移植到axis组件上,axis结合spring,其实也就是获取spring的bean,首先在web.xml中配置axis的servlet:
- <servlet>
- <servlet-name>axis</servlet-name>
- <servlet-class >
- org.apache.axis.transport.http.AxisServlet
- </servlet-class >
- <load-on-startup>3 </load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>axis</servlet-name>
- <url-pattern>/servlet/AxisServlet</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>axis</servlet-name>
- <url-pattern>*.jws</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>axis</servlet-name>
- <url-pattern>/services/*</url-pattern>
- </servlet-mapping>
接着定义你的webservice的接口,继承ServletEndpointSupport,并在其onInit方法中加载Spring的bean:
- public class Caculator exends ServletEndpointSupport{
- protected void onInit() throws ServiceException{
- service = getApplicationContext().getBean("calculatorService " );
- }
- public ResponseMsg caculate( int a, int b, String operation){
- return service.caculate(a,b,operation);
- }
- }
下一步定义wsdd文件,声明该接口:
- <?xml version= "1.0" encoding= "UTF-8" ?>
- <deployment xmlns="http://xml.apache.org/axis/wsdd/"
- xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" >
- <globalConfiguration>
- <parameter name="adminPassword" value= "admin" />
- <parameter name="sendXsiTypes" value= "true" />
- <parameter name="sendMultiRefs" value= "true" />
- <parameter name="sendXMLDeclaration" value= "true" />
- <parameter name="axis.sendMinimizedElements" value= "true" />
- <requestFlow>
- <handler type="java:org.apache.axis.handlers.JWSHandler" >
- <parameter name="scope" value= "session" />
- </handler>
- <handler type="java:org.apache.axis.handlers.JWSHandler" >
- <parameter name="scope" value= "request" />
- <parameter name="extension" value= ".jwr" />
- </handler>
- </requestFlow>
- </globalConfiguration>
- <handler name="Authenticate"
- type="java:org.apache.axis.handlers.SimpleAuthenticationHandler" />
- <handler name="LocalResponder"
- type="java:org.apache.axis.transport.local.LocalResponder" />
- <handler name="URLMapper" type= "java:org.apache.axis.handlers.http.URLMapper" />
- <!-- 定义WebService的管理台 -->
- <service name="AdminService" provider= "java:MSG" >
- <parameter name="allowedMethods" value= "AdminService" />
- <parameter name="enableRemoteAdmin" value= "false" />
- <parameter name="className" value= "org.apache.axis.utils.Admin" />
- <namespace>http://xml.apache.org/axis/wsdd/</namespace>
- </service>
- <!-- 定义你的服务接口 -->
- <service name="Caculator" provider= "java:RPC" use= "literal" >
- <parameter name="allowedMethods" value= "*" />
- <parameter name="className"
- value="com.raymon.Caculator" />
- <beanMapping encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
- serializer="org.apache.axis.encoding.ser.JDomElementSerializerFactory"
- deserializer="org.apache.axis.encoding.ser.JDomElementDeserializerFactory"
- languageSpecificType="java:com.raymon.bean.ResponseMsg"
- name="ns:ResponseMsg" regenerateElement= "true" xmlns:ns= "urn:BeanService" />
- </service>
- <!-- 定义WebSerivice的系统服务。 -->
- <service name="Version" provider= "java:RPC" >
- <parameter name="allowedMethods" value= "getVersion" />
- <parameter name="className" value= "org.apache.axis.Version" />
- </service>
- <transport name="http" >
- <requestFlow>
- <handler type="URLMapper" />
- <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler" />
- </requestFlow>
- </transport>
- <transport name="local" >
- <responseFlow>
- <handler type="LocalResponder" />
- </responseFlow>
- </transport>
- </deployment>
到此为止,webservice的服务器端已经定义结束,注意自定义返回类型ResponseMsg的配置。
客户端代码:
- public static void main(String [] args){
- try {
- String endPoint = "http://1.1.1.1:8080/services/Caculator" ;
- Service service = new Service();
- Call call = (Call)service.createCall();
- Qname qname = new Qname( "urn:BeanService" , "ResponseMsg" );
- call.registerTypeMapping(ResponseMsg.class ,qname, new BeanSerializerFactory(ResponseMsg. class ,qname), new BeanDeserializerFactory(ResponseMsg. class ,qname));
- call.setReturnClass(ResponseMsg.class );
- call.addParameter("in0" ,XMLType.XSD_INTEGER,ParameterMode.IN);
- call.addParameter("in1" ,XMLType.XSD_STRING,ParameterMode.IN);
- call.addParameter("in2" ,XMLType.XSD_STRING,ParameterMode.IN);
- URL url = new URL(endPoint);
- call.setTargetEndpointAddress(url);
- Qname caculate = new Qname(endPoint, "caculate" );
- call.setOperationName(caculate);
- ResponseMsg response = call.invoke(new Ojbect[]{ 2 , 3 , "*" });
- }catch (Exception e){
- e.printStackTrace();
- }
- }