我有一个web服务,我正在尝试建立一个客户端.
我有以下wsdl:
http://www.cmicdataservices.com/datacenter/service.asmx?wsdl
它需要身份验证.查看WSDL描述,我看不到采用身份验证对象的方法,也没有使用用户名和密码作为参数.使用Netbeans我已经为WSDL生成了jax-ws源代码.然而,我无法弄清楚在那之后该怎么做.
使用soapui我可以连接到webservice并运行所有方法.但是我再一次想把它构建成一个可以在没有我交互的情况下运行的客户端.
我的问题在于弄清楚如何使用这个生成的代码,看起来netbeans.tv有一个视频(netbeans soapui插件视频2),后来丢失了.有没有人知道任何教程或知道如何使用这个生成的代码访问Web服务的任何示例?
所以我有一个方法CheckifAuthorized()
在soapui中运行我得到以下xml
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:cmic="http://www.cmicdataservices.com/"> <soap:Header> <cmic:Authentication> <!--Optional:--> <cmic:UserName>username</cmic:UserName> <!--Optional:--> <cmic:Password>password</cmic:Password> </cmic:Authentication> </soap:Header> <soap:Body> <cmic:CheckIfAuthorized/> </soap:Body> </soap:Envelope>
然后,我可以在soap ui中运行该请求,并获得认证成功的响应.
使用netbeans和soapui生成的jax-ws代码,我有以下内容:
package javaapplication7; /** * * @author grant */ public class Main { public static void main(String[] args) { Boolean result = checkIfAuthorized(); System.out.println("The result is: " + result); } private static boolean checkIfAuthorized() { javaapplication7.CMICDatacenterService service = new javaapplication7.CMICDatacenterService(); javaapplication7.CMICDatacenterServiceSoap port = service.getCMICDatacenterServiceSoap(); return port.checkIfAuthorized(); } }
这将失败,并出现以下错误
run: Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Server was unable to process request. ---> Object reference not set to an instance of an object. at com.sun.xml.internal.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:178) at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:111) at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:108) at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78) at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:107) at $Proxy30.checkIfAuthorized(Unknown Source) at javaapplication7.Main.checkIfAuthorized(Main.java:24) at javaapplication7.Main.main(Main.java:17) Java Result: 1
这是我在尝试使用python进行服务时遇到的同样问题.我已经选择使用Java,因为我觉得我可以更快地解析xml和创建对象,因为我已经创建了这个实体.
谢谢.
格兰特
我不想回答这个问题,因为我仍然想知道我能在这里做些什么,但我最后还是用手写下了这个请求.现在我可以将它转换为一个xml对象,并按照我的方式进行,但我想,soapui使这一切变得更加容易.我真正不明白的是如何使用soapui来构建此请求并将其合并到我的项目中:
public class Main { public final static String DEFAULT_SERVER = "http://www.cmicdataservices.com/datacenter/service.asmx"; public final static String SOAP_ACTION = "http://www.cmicdataservices.com/CheckIfAuthorized"; public static void main(String[] args) { String server = DEFAULT_SERVER; String UserName = "Username"; String Password="Password"; try{ URL url = new URL(server); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type","application/soap+xml; charset=utf-8"); connection.setRequestProperty("Host","www.cmicdataservices.com"); OutputStream out = connection.getOutputStream(); Writer wout = new OutputStreamWriter(out); // Uncomment the following and comment out the prevIoUs two lines to see your xml //BufferedWriter wout = new BufferedWriter(new FileWriter("/tmp/testXML.xml")); //Start writing soap request - Envelope wout.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"); wout.write("<soap12:Envelope "); wout.write("xmlns:xsi="); wout.write("'http://www.w3.org/2001/XMLSchema-instance' "); wout.write("xmlns:xsd="); wout.write("'http://www.w3.org/2001/XMLSchema' "); wout.write("xmlns:soap12="); wout.write("'http://www.w3.org/2003/05/soap-envelope'>\r\n"); //Soap request header start wout.write("<soap12:Header>\r\n"); //Start writing soap request - Authentication wout.write("<Authentication xmlns="); wout.write("'http://www.cmicdataservices.com/'>\r\n"); wout.write("<UserName>" + UserName + "</UserName>\r\n"); wout.write("<Password>" + Password + "</Password>\r\n"); // End Authentication wout.write("</Authentication>\r\n"); //End the header wout.write("</soap12:Header>\r\n"); //Start writing the body wout.write("<soap12:Body>"); wout.write("<GetCurrentDataVer1 xmlns="); wout.write("'http://www.cmicdataservices.com/' />\r\n"); // End the Body wout.write("</soap12:Body>\r\n"); // End the Envelope wout.write("</soap12:Envelope>\r\n"); wout.flush(); wout.close(); //BufferedWriter fout = new BufferedWriter(new FileWriter("/tmp/testXMLResponse.xml")); InputStream in = connection.getInputStream(); createFile(in,"/tmp/testXMLResponse.xml"); } catch (IOException e) { System.err.println(e); } } public static void createFile(InputStream io,String fileName) throws IOException { FileOutputStream fout = new FileOutputStream(fileName); byte[] buf = new byte[256]; int read = 0; while ((read = io.read(buf)) != -1){ fout.write(buf,read); } }
解决方法
您的代码的问题是SOAP标头中缺少Authentication元素.看看WSDL,它应该始终存在:
<wsdl:operation name="CheckIfAuthorized"> <soap:operation soapAction="http://www.cmicdataservices.com/CheckIfAuthorized" style="document"/> <wsdl:input> <soap:body use="literal"/> <soap:header message="tns:CheckIfAuthorizedAuthentication" part="Authentication" use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation>
当CheckIfAuthorized请求中没有Authentication元素时,由于XML不正确,服务器会因异常而失败.下面是Python中的示例客户端,用于演示解决问题的想法,我认为将其转换为Java不是问题.
from suds.client import Client client = Client("http://www.cmicdataservices.com/datacenter/service.asmx?wsdl") auth = client.factory.create('Authentication') auth.UserName = "username" auth.Password = "password" client.set_options(soapheaders=auth) client.service.CheckIfAuthorized()