【问题标题】:Why is this simple SOAP client not working (org.apache.http)?为什么这个简单的 SOAP 客户端不起作用(org.apache.http)?
【发布时间】:2012-10-01 10:18:18
【问题描述】:

我想将 XML 文件作为请求发送到 SOAP 服务器。 这是我的代码:(修改自Sending HTTP Post request with SOAP action using org.apache.http

import org.apache.http.client.*;
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.protocol.HTTP;
import org.apache.http.HttpResponse;
import java.net.URI;

public static void req()   {
        try {
            HttpClient httpclient = new DefaultHttpClient();
            String body="xml here";
            String bodyLength=new Integer(body.length()).toString();

            URI uri=new URI("http://1.1.1.1:100/Service");
            HttpPost httpPost = new HttpPost(uri);
            httpPost.setHeader( "SOAPAction", "MonitoringService" );
            httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8");


            StringEntity entity = new StringEntity(body, "text/xml",HTTP.DEFAULT_CONTENT_CHARSET);
            httpPost.setEntity(entity);

            RequestWrapper requestWrapper=new RequestWrapper(httpPost);
            requestWrapper.setMethod("POST");


            requestWrapper.setHeader("Content-Length",bodyLength);
            HttpResponse response = httpclient.execute(requestWrapper);
            System.out.println(response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

在此之前,我从服务器收到错误“http 500”(内部服务器错误),但现在我根本没有得到任何回复。我知道服务器工作正常,因为其他客户端没有问题。

谢谢。

【问题讨论】:

  • 你说的“之前”是什么意思?如果你发送一个有效的 xml 字符串而不是 xml here 会发生什么?
  • 请说明您是否使用IDE,如果是,那么。如果您使用的是诸如 Oracle Jdeveloper 11g 之类的 IDE,那么只需导入 WSDL,IDE 就会自动生成代码。
  • 您应该发布请求的正文。如果您的 xml 有问题,您可能不会得到任何响应。

标签: java http post soap apache-commons-httpclient


【解决方案1】:

尝试像这样发送请求。这就是我上次的做法:

try
        {
            StringBuffer strBuffer = new StringBuffer();
            HttpURLConnection connection = connectToEndPoint(endpoint);
            OutputStream outputStream = generateXMLOutput(connection, yourvalue, strDate);

            InputStream inputStream = connection.getInputStream();

            int i;
            while ((i = inputStream.read()) != -1) {
                Writer writer = new StringWriter();
                writer.write(i);
                strBuffer.append(writer.toString());

            String status = xmlOutputParse(strBuffer);

以及使用的功能:

private static HttpURLConnection connectToEndPoint(String wsEndPoint) throws MalformedURLException, IOException {
    URL urlEndPoint = new URL(wsEndPoint);
    URLConnection urlEndPointConnection = urlEndPoint.openConnection();
    HttpURLConnection httpUrlconnection = (HttpURLConnection) urlEndPointConnection;
    httpUrlconnection.setDoOutput(true);
    httpUrlconnection.setDoInput(true);
    httpUrlconnection.setRequestMethod("POST");
    httpUrlconnection.setRequestProperty("content-type", "application/soap+xml;charset=UTF-8");
    // set connection time out to 2 seconds
    System.setProperty("sun.net.client.defaultConnectTimeout", String.valueOf(2 * 1000));
    // httpUrlconnection.setConnectTimeout(2*1000);
    // set input stream read timeout to 2 seconds
    System.setProperty("sun.net.client.defaultReadTimeout", String.valueOf(2 * 1000));
    // httpUrlconnection.setReadTimeout(2*1000);
    return httpUrlconnection;
}

您在哪里手动创建 xml(根据您的需要进行修改):

private static OutputStream generateXMLOutput(HttpURLConnection conn, String msisdn, String strDate) throws IOException {
    OutputStream outputStream = conn.getOutputStream();

    StringBuffer buf = new StringBuffer();

    buf.append("<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:ins=\"http://yournamespace">\r\n");
    buf.append("<soap:Header xmlns:wsa=\"http://www.w3.org/2005/08/addressing\">\r\n");

    //..... append all your lines .......       

    OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");

    outputStreamWriter.write("<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:ins=\"http://yournamespace\">\r\n");
    outputStreamWriter.write("<soap:Header xmlns:wsa=\"http://www.w3.org/2005/08/addressing\">\r\n");
    //..... write all your lines .......    

    outputStreamWriter.flush();

    outputStream.close();
    return outputStream;
}

以及返回您的 WS 答案的函数:

private static String xmlOutputParse(StringBuffer xmlInputParam) throws IOException, ParserConfigurationException, SAXException {
    String status = null;
    DocumentBuilderFactory docBuilderfFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder documentBuilder = docBuilderfFactory.newDocumentBuilder();
    InputSource inputSource = new InputSource();
    inputSource.setCharacterStream(new StringReader(xmlInputParam.toString()));
    Document document = documentBuilder.parse(inputSource);
    NodeList nodeList = document.getElementsByTagName("ResponseHeader");
    Element element = (Element) nodeList.item(0);
    if (element == null) {
        return null;
    }
    NodeList name = element.getElementsByTagName("Status");
    Element line = (Element) name.item(0);
    if (line == null) {
        return null;
    }
    if (line.getFirstChild() instanceof CharacterData) {
        CharacterData cd = (CharacterData) line.getFirstChild();
        status = cd.getData().trim();
    }
    return status;
}

我认为这个解决方案(尽管很长)适用于大多数情况。我希望你能适应你的需要。

最好的问候!

【讨论】:

    【解决方案2】:

    org.apache.http API 不支持 SOAP/Web 服务,因此您正在以非标准方式完成棘手的工作。该代码对 java 不是很友好或灵活,因为它不能自动将 java 对象数据“绑定”(转换)到 SOAP 请求和 SOAP 响应之外。调试和开始工作有点冗长、棘手,而且很脆弱 - 您是否在处理完整的 SOAP 协议,包括故障处理等?

    我可以建议使用 JAX-WS 标准吗,它内置在 JVM 中:

    1.将 WSDL 文件保存到本地磁盘
    例如。 &lt;app path&gt;/META-INF/wsdl/abc.com/calculator/Calculator.wsdl
    如果您没有 WSDL,您可以在浏览器中输入并将结果页面保存到磁盘:
    http://abc.com/calculator/Calculator?wsdl

    2。使用 wsimport 命令将 WSDL 转换为 java 类文件
    对于 JDK,工具位于 &lt;jdkdir&gt;\bin\wsimport.exe (or .sh)
    对于应用服务器,将类似于 &lt;app_server_root&gt;\bin\wsimport.exe (or .sh)

    &lt;filepath&gt;\wsimport -keep -verbose &lt;wsdlpath&gt;\Calculator.wsdl

    或者,如果您的 WSDL 可通过预先存在的 Web 服务获得

    &lt;filepath&gt;\wsimport -keep -verbose http://abc.com/calculator/Calculator?wsdl

    (也可以包含“-p com.abc.calculator”来设置生成类的包)

    会生成如下文件 - 在您的 java 项目中包含这些源文件:

    com\abc\calculator\ObjectFactory.java       
    com\abc\calculator\package-info.java       
    com\abc\calculator\Calculator.java       ............................name = `<wsdl:portType>` name attribute      
    com\abc\calculator\CalculatorService.java     ................name = `<wsdl:service>` name attribute    
    com\abc\calculator\CalculatorRequestType.java  .......name = schema type used in input message    
    com\abc\calculator\CalculatorResultType.java ..........name = schema type used in output message
    

    2。创建 JAX-WS SOAP Web 服务客户端

    package com.abc.calculator.client;
    
    import javax.xml.ws.WebServiceRef;
    import com.abc.calculator.CalculatorService;
    import com.abc.calculator.Calculator;
    
    public class CalculatorClient {
    
        @WebServiceRef(wsdlLocation="META-INF/wsdl/abc.com/calculator/Calculator.wsdl")
        // or @WebServiceRef(wsdlLocation="http://abc.com/calculator/Calculator?wsdl")
        public static CalculatorService calculatorService;
    
        public CalculatorResponseType testCalculation() {
            try {
                CalculatorRequestType request = new CalculatorRequest();
                request.setSomeParameter("abc");
                request.setOtherParameter(3);
                Calculator calculator = calculatorService.getCalculatorPort();
                // automatically generate SOAP XML message, send via HTTP, 
                // receive & marshal response to java object 
                String response = calculator.doCalculation(response);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-25
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多