问题描述
大家好:最近一直在做webservice 相关的东西。 webservice 的特性要是跨平台,跨语言。 我自己分别用 Java 和 Python 搭建了两套webservice(从某种意义上来讲,不仅是兴趣爱好,也是企业需求). 其中Java中使用Axis2框架,server 端和client端可以正常交互。 Python 中,server 端使用的是 tornadows(tornadow webservice), 客户端使用的是 suds, server 端和client端也可以正常交互。既然webservice 是跨平台的,我用python client 端来访问 Axis2 serve端,最早有一些 encoding 的问题,最后也解决了。现在我用 Axis2 client 访问我的 python server 端,一直不成功。 Axis2 client 收到的结果为null, python server端没有收到Axis2 client 的请求。 同样的python server, 我用python client(suds) 是可以的。现在我把我的 python server 端的code, 在浏览器中访问得到的wsdl 文件,以及 Axis2 client的code 一起贴上来。 希望高手轻移尊步,帮我指点迷津。part1: python server#NOTE: 功能很简单,就是提供一个getPrice() 方法,接受一个整数,返回一个整数import loggingimport tornado.httpserverimport tornado.ioloopimport tornado.webfrom tornadows import soaphandlerfrom tornadows import webservicesfrom tornadows import xmltypesfrom tornadows.soaphandler import webservicefrom tornado.options import define, optionsdefine('mode', default='deploy')define('port', type=int, default=8001)options['logging'].set('warning')class SMSService(soaphandler.SoapHandler): @webservice(_params=xmltypes.Integer,_returns=xmltypes.Integer) def getPrice(self,a): print 'come here' return 1987if __name__ == '__main__': service = [('SMSService',SMSService)] app = webservices.WebService(service) ws = tornado.httpserver.HTTPServer(app) ws.listen(options.port) logging.warn("SMSService running on: localhost:%d", options.port) tornado.ioloop.IOLoop.instance().start()part 2: wsdl #NOTE: 在浏览器中输入 ”http://172.16.2.46:8001/SMSService?wsdl“ 得到wsdl 文件如下:<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://127.0.1.1:8001/SMSService/getPrice" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="SMSService" targetNamespace="http://127.0.1.1:8001/SMSService/getPrice"><wsdl:types><xsd:schema targetNamespace="http://127.0.1.1:8001/SMSService/getPrice"><xsd:complexType name="paramsTypes"><xsd:sequence><xsd:element name="a" type="xsd:integer"/></xsd:sequence></xsd:complexType><xsd:element name="params" type="tns:paramsTypes"/><xsd:element name="returns" type="xsd:integer"/></xsd:schema></wsdl:types><wsdl:message name="SMSServiceRequest"><wsdl:part element="tns:params" name="parameters"/></wsdl:message><wsdl:message name="SMSServiceResponse"><wsdl:part element="tns:returns" name="parameters"/></wsdl:message><wsdl:portType name="SMSServicePortType"><wsdl:operation name="getPrice"><wsdl:input message="tns:SMSServiceRequest"/><wsdl:output message="tns:SMSServiceResponse"/></wsdl:operation></wsdl:portType><wsdl:binding name="SMSServiceBinding" type="tns:SMSServicePortType"><soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/><wsdl:operation name="getPrice"><soap:operation soapAction="http://127.0.1.1:8001/SMSService" style="document"/><wsdl:input><soap:body use="literal"/></wsdl:input><wsdl:output><soap:body use="literal"/></wsdl:output></wsdl:operation></wsdl:binding><wsdl:service name="SMSService"><wsdl:port binding="tns:SMSServiceBinding" name="SMSServicePort"><soap:address location="http://127.0.1.1:8001/SMSService"/></wsdl:port></wsdl:service></wsdl:definitions>part 3: Axis2 clientpackage client;import javax.xml.namespace.QName;import org.apache.axis2.addressing.EndpointReference;import org.apache.axis2.client.Options;import org.apache.axis2.rpc.client.RPCServiceClient;public class client_for_python {public static void main(String[] args) throws Exception {// step 1: 使用RPC方式调用WebServiceRPCServiceClient serviceClient = new RPCServiceClient();Options options = serviceClient.getOptions();// step 2: 指定调用WebService的URL// url for pythonString url2 = "http://172.16.2.46:8001/SMSService";EndpointReference targetEPR = new EndpointReference(url2);options.setTo(targetEPR);// step 3: 指定getGreeting方法的参数值// step 5-6: (similiar whit// it!)下面是调用getPrice方法的代码,这些代码与调用getGreeting方法的代码类似Class[] classes = new Class[] { int.class };QName opAddEntry = new QName("http://172.16.2.46:8001/SMSService/getPrice");System.out.println(serviceClient.invokeBlocking(opAddEntry,new Object[] {1}, classes)[0]);}}#NOTE: 没有任何输出:控制台上的所有输出就是:log4j:WARN No appenders could be found for logger (org.apache.axis2.context.AbstractContext).log4j:WARN Please initialize the log4j system properly.null在python server 端也没有收到任何参数。我个人分析,可能是 Axis2 端 url 的指向有问题,可以看了一部分API, 也做了一些尝试,还是不行。Hope someone can give me some points.Thanks! (The blog permit not to use GaoShao BanMang,hehe!)-- Jia Xiaolei
解决方案
我不知道你代码怎么做的,但是我可以告诉你怎么去解决这个问题,最简单有效的方法就是抓包,1.先确认请求能到服务端。2.从服务端抓两种不同客户端的访问过来的SOAP包。把两个抓到的包做对比,看看有什么不一样。排查代码问题还是网络问题,还是什么名空间的问题。祝你好运!
解决方案二:
抓包用这个 tcpmon,我比较喜欢的。