小生今日刚从.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,导致程序出错。请问大家,为什么会发生这种问题,是不是还少写了部分功能代码呢?

解决方案 »

  1.   

                            OutputStream   os=conn.getOutputStream(); 
                            OutputStreamWriter   osw=new   OutputStreamWriter(os,"utf-8"); 
                            osw.write(soap); 
                            osw.flush(); 
                            osw.close(); // 去掉这一句                        InputStream   is=conn.getInputStream(); 
      

  2.   

    谢谢楼上的前辈指导,但是注释掉osw.close(); 后,异常依旧java.io.IOException: Server returned HTTP response code: 400 for URL: http://192.168.0.95/SoapSetup/Service.asmx
    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是可以访问的。
      

  3.   

    有没有可能是因为WebServices上的类没有进行序列化的原因呢?
      

  4.   

    conn.setDoInput(true); 
    conn.setDoOutput(true); 
    con.setRequestMethod("POST"); // 你为何少了这个呢?400 错误就是请求无效
      

  5.   

    楼上的前辈:
    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();但是错误依旧……
      

  6.   

    .NET的WebServices上有方法如下:
    [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变量中……
      

  7.   

    按有几个群,你不妨加进去,可以和大家一起讨论啊.........46986340,28039577,4804620                                                                                                                                           
    在那里看看有无能回答你的,谢谢,LZ,甭忘了给俺分哦,谢谢LZ
      

  8.   

    第二种方法的问题解决了,原因出在这一句:
    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);成功运行……激动啊……接下来研究传递复杂的数据类型去……