为什么这个简单的SOAP客户端不工作(org.apache.http)?

我想将一个XML文件作为请求发送到SOAP服务器。 这是我的代码:( 使用org.apache.http从使用SOAP操作发送HTTP Post请求进行了修改)

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’(内部服务器错误),但现在我没有得到任何回复。 我知道服务器工作正常,因为与其他客户端没有问题。

谢谢。

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

我是否可以建议使用内置于JVM中的JAX-WS标准:

1.将WSDL文件保存到本地磁盘
例如/META-INF/wsdl/abc.com/calculator/Calculator.wsdl
如果您没有WSDL,则可以键入浏览器并将结果页面保存到磁盘:
http://abc.com/calculator/Calculator?wsdl

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

\wsimport -keep -verbose \Calculator.wsdl

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

\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 = `` name attribute com\abc\calculator\CalculatorService.java ................name = `` 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(); } } } 

尝试发送这样的请求。 这是我上次这样做的方式:

 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); 

并使用的function:

 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("\r\n"); buf.append("\r\n"); //..... append all your lines ....... OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8"); outputStreamWriter.write("\r\n"); outputStreamWriter.write("\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; } 

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

最好的祝福 !