小生今日刚从.NET转入JAVA的一个项目,该项目要求用JAVA编写的客户端可以使用SOAP1.1,SOAP1.2与.NET的WebServices进行数据通信。为了测试,写了一个已有的WebServices,其请求的SOAP1.1示例为:POST /SoapSetup/Service.asmx HTTP/1.1
Host: 192.168.0.95
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/Operation"<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Operation xmlns="http://tempuri.org/">
<indata>
<strOperator>string</strOperator>
<dOperand1>double</dOperand1>
<dOperand2>double</dOperand2>
</indata>
</Operation>
</soap:Body>
</soap:Envelope>现用JAVA编写的类如下:
package clientServices.soap;import java.io.*;
import java.net.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;public class Soap {
private static String getSoapRequest(String strOperator,String dOperand1,String dOperand2)
{
try
{
InputStream is=new FileInputStream("./clientServices/soap/OperationSoap.xml");
InputStreamReader isr=new InputStreamReader(is);
BufferedReader reader=new BufferedReader(isr);
String soap="";
String tmp;
while((tmp=reader.readLine())!=null)
{
soap+=tmp;
}
reader.close();
isr.close();
soap=soap.replace("${strOperator}$", strOperator);
soap=soap.replace("${dOperand1}$", dOperand1);
soap=soap.replace("${dOperand2}$", dOperand2);
soap=soap.replace("${length}$", Integer.toString(soap.length()));
return soap;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
/*
* 返回InputStream是因为w3c DOM中Document的parse方法可
* 以接受InputStream类型的参数,方面在下一步对XML的解释
*/
private static InputStream getSoapInputStream(String strOperator,String dOperand1,String dOperand2)throws Exception
{
try
{
String soap=getSoapRequest(strOperator,dOperand1,dOperand2);
if(soap==null)
{
return null;
}
URL url=new URL("http://192.168.0.95/SoapSetup/Service.asmx");
URLConnection conn=url.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true); conn.setRequestProperty("Content-Length", Integer.toString(soap.length()));
conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
conn.setRequestProperty("SOAPAction","http://tempuri.org/Operation");
OutputStream os=conn.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os,"utf-8");
osw.write(soap);
osw.flush();
osw.close(); InputStream is=conn.getInputStream();
return is;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
/*
* 用W3C DOM对返回的XML进行解释
*/
public static String getValue(String strOperator,String dOperand1,String dOperand2)
{
try
{
Document doc;
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db=dbf.newDocumentBuilder();
InputStream is=getSoapInputStream(strOperator,dOperand1,dOperand2);
doc=db.parse(is);
NodeList nl=doc.getElementsByTagName("retValue");
Node n=nl.item(0);
String weather=n.getFirstChild().getNodeValue();
is.close();
return weather;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
} /**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成方法存根
System.out.println(Soap.getValue("+","45","56"));
}
}当程序执行到getSoapInputStream()函数中的InputStream is=conn.getInputStream();时就会返回一个为null的InputStream,导致程序出错。请问大家,为什么会发生这种问题,是不是还少写了部分功能代码呢?
Host: 192.168.0.95
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/Operation"<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Operation xmlns="http://tempuri.org/">
<indata>
<strOperator>string</strOperator>
<dOperand1>double</dOperand1>
<dOperand2>double</dOperand2>
</indata>
</Operation>
</soap:Body>
</soap:Envelope>现用JAVA编写的类如下:
package clientServices.soap;import java.io.*;
import java.net.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;public class Soap {
private static String getSoapRequest(String strOperator,String dOperand1,String dOperand2)
{
try
{
InputStream is=new FileInputStream("./clientServices/soap/OperationSoap.xml");
InputStreamReader isr=new InputStreamReader(is);
BufferedReader reader=new BufferedReader(isr);
String soap="";
String tmp;
while((tmp=reader.readLine())!=null)
{
soap+=tmp;
}
reader.close();
isr.close();
soap=soap.replace("${strOperator}$", strOperator);
soap=soap.replace("${dOperand1}$", dOperand1);
soap=soap.replace("${dOperand2}$", dOperand2);
soap=soap.replace("${length}$", Integer.toString(soap.length()));
return soap;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
/*
* 返回InputStream是因为w3c DOM中Document的parse方法可
* 以接受InputStream类型的参数,方面在下一步对XML的解释
*/
private static InputStream getSoapInputStream(String strOperator,String dOperand1,String dOperand2)throws Exception
{
try
{
String soap=getSoapRequest(strOperator,dOperand1,dOperand2);
if(soap==null)
{
return null;
}
URL url=new URL("http://192.168.0.95/SoapSetup/Service.asmx");
URLConnection conn=url.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true); conn.setRequestProperty("Content-Length", Integer.toString(soap.length()));
conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
conn.setRequestProperty("SOAPAction","http://tempuri.org/Operation");
OutputStream os=conn.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os,"utf-8");
osw.write(soap);
osw.flush();
osw.close(); InputStream is=conn.getInputStream();
return is;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
/*
* 用W3C DOM对返回的XML进行解释
*/
public static String getValue(String strOperator,String dOperand1,String dOperand2)
{
try
{
Document doc;
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db=dbf.newDocumentBuilder();
InputStream is=getSoapInputStream(strOperator,dOperand1,dOperand2);
doc=db.parse(is);
NodeList nl=doc.getElementsByTagName("retValue");
Node n=nl.item(0);
String weather=n.getFirstChild().getNodeValue();
is.close();
return weather;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
} /**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成方法存根
System.out.println(Soap.getValue("+","45","56"));
}
}当程序执行到getSoapInputStream()函数中的InputStream is=conn.getInputStream();时就会返回一个为null的InputStream,导致程序出错。请问大家,为什么会发生这种问题,是不是还少写了部分功能代码呢?
OutputStreamWriter osw=new OutputStreamWriter(os,"utf-8");
osw.write(soap);
osw.flush();
osw.close(); // 去掉这一句 InputStream is=conn.getInputStream();
null
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1241)
at clientServices.soap.Soap.getSoapInputStream(Soap.java:70)
at clientServices.soap.Soap.getValue(Soap.java:93)
at clientServices.soap.Soap.main(Soap.java:113)
java.lang.IllegalArgumentException: InputStream cannot be null
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:120)
at clientServices.soap.Soap.getValue(Soap.java:94)
at clientServices.soap.Soap.main(Soap.java:113)在IE中,http://192.168.0.95/SoapSetup/Service.asmx是可以访问的。
conn.setDoOutput(true);
con.setRequestMethod("POST"); // 你为何少了这个呢?400 错误就是请求无效
URLConnection类并没有setRequestMethod()方法,因此使用HttpURLConnection conn=(HttpURLConnection)url.openConnection();进行强制转换URL url=new URL("http://192.168.0.95/SoapSetup/Service.asmx");
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
……
//osw.close();但是错误依旧……
[WebMethod]
public string Hello(string name)
{
return "Hello! " + name;
}这次使用了另一种方法:package clientServices1.soap1;import org.apache.axis.client.Service;
import org.apache.axis.client.Call;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;public class Soap1 {
public static void main(String[] args) { String result = "";
try {
String name="Arieslns";
String endpoint = "http://192.168.0.95/SoapSetup/Service.asmx";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName(new QName("http://tempuri.org/", "Hello"));
call.addParameter("name", org.apache.axis.Constants.XSD_STRING,ParameterMode.IN);
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);
call.setUseSOAPAction(true);
call.setSOAPActionURI("http://tempuri.org/Hello");
result = (String)call.invoke(new Object[]{name});
}
catch (Exception e) {
System.err.println(e.toString());
e.printStackTrace();
}
System.out.println(result);
}
}但是返回值的仅仅是在控制台输出的:Hello!
然后在WebServices方法中添加了:Flie.AppendAllText(@"C:\result.txt",name);
结果生成的文件没有任何内容,参数并没有传递到name变量中……
在那里看看有无能回答你的,谢谢,LZ,甭忘了给俺分哦,谢谢LZ
call.addParameter("name", org.apache.axis.Constants.XSD_STRING,ParameterMode.IN);
因为addParameter()的第一个参数没有指定命名空间,所以找不到名为“name”的参数。
这样稍微修改下就可以了:
call.addParameter(new QName("http://tempuri.org/", "name"), org.apache.axis.encoding.XMLType.XSD_STRING,ParameterMode.IN);成功运行……激动啊……接下来研究传递复杂的数据类型去……