我正在将Applet转换为桌面应用程序,其中一个内部程序服务包括一个SOAP客户端,旨在将信息发送到远程服务器。以下是负责此流程的代码:
package my.package.app.utils;
import my.package.app.main.MainClass;
import my.package.app.org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SoapClient {
public static JSONObject callMethod(String path, String method, Object... args) {
HttpURLConnection connection = null;
String data = null;
try {
data = parseXML(method, args);
MainClass.debug("Making http POST connections to : " + path);
URL u = new URL(path);
URLConnection uc = u.openConnection();
connection = (HttpURLConnection) uc;
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("SOAPAction", method);
connection.setUseCaches(false);
OutputStream out = connection.getOutputStream();
Writer wout = new OutputStreamWriter(out);
wout.write(data);
wout.flush();
wout.close();
InputStream in = connection.getInputStream();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(in);
doc.getDocumentElement().normalize();
NodeList childs = doc.getElementsByTagName("return");
String responseText = childs.item(0).getTextContent();
if ("false".equals(responseText)) {
return null;
}
JSONObject response = new JSONObject(responseText);
in.close();
return response;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
private static String parseXML(String method, Object... args) {
StringBuilder xml = new StringBuilder();
xml.append(XMLTemplates.soapHeader);
xml.append("<ns1:");
xml.append(method);
xml.append(">");
for (int i = 0; i < args.length; i++) {
String dataType = "xsi:type=\"xsd:string\"";
xml.append("<param");
xml.append(i);
xml.append(" ");
if (args[i] instanceof Integer) {
dataType = "xsi:type=\"xsd:integer\"";
}
if (args[i] instanceof Double) {
dataType = "xsi:type=\"xsd:decimal\"";
}
if (args[i] instanceof Boolean) {
dataType = "xsi:type=\"xsd:boolean\"";
}
xml.append(dataType);
xml.append(">");
xml.append(String.valueOf(args[i]));
xml.append("</param");
xml.append(i);
xml.append(">");
}
xml.append("</ns1:");
xml.append(method);
xml.append(">");
xml.append(XMLTemplates.soapFooter);
return xml.toString();
}
}
当使用 callMethod 时,它会在我的案例中收到一个路径字符串,其中包含带有HTTPS协议的网址,如下所示:&#34; https://fileserver.myserver.net:9000/lf_soap_document_server_main.php& #34;
使用该网址运行 callMethod 时,小程序的Java控制台会显示以下内容:
18:15:45.476-DEBUG: Making http POST connections to : https://fileserver.myserver.net:9000/lf_soap_document_server_main.php
network: Connecting https://fileserver.myserver.net:9000/lf_soap_document_server_main.php with proxy=DIRECT
network: Connecting http://fileserver.myserver.net:9000/ with proxy=DIRECT
并且该过程成功完成。
但是当从桌面应用程序版本执行相同的代码时,会发生以下情况:
18:28:29.991-DEBUG: Making http POST connections to : https://fileserver.myserver.net:9000/lf_soap_document_server_main.php
network: Connecting https://fileserver.myserver.net:9000/lf_soap_document_server_main.php with proxy=DIRECT
network: Connecting socket://fileserver.myserver.net:9000 with proxy=DIRECT
java.net.ConnectException: Connection timed out: connect
当 OutputStream out = connection.getOutputStream(); 被调用时,会出现问题。请注意,日志消息将URL的协议从https://更改为socket://,并且似乎也删除了最后一个斜杠(/)。
这是一个完整的例外:
java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.security.ssl.SSLSocketImpl.connect(Unknown Source)
at sun.net.NetworkClient.doConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.<init>(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.New(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$6.run(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$6.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessController.doPrivilegedWithCombiner(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.access$100(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$8.run(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$8.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessController.doPrivilegedWithCombiner(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
at my.package.app.utils.SoapClient.callMethod(SoapClient.java:42)
at my.package.app.services.scanner.LFScanner$SoapUpload.run(LFScanner.java:746)
桌面应用程序使用Jetty创建与安全websocket服务器的连接,并在用户的计算机上创建本地websocket服务器,但它们都没有与发生问题的SoapClient类建立业务关系。 / p>
我已经测试过为连接设置了5分钟超时并读取了HttpURLConnection实例,但问题仍然在不到一分钟的时间内在桌面应用程序上发生。
我使用1.8.0_111-b14作为运行时来执行程序(applet和桌面应用程序),在Windows 10机器上,64位。
我需要知道此代码是否有任何问题,或者此处是否缺少设置以防止这种情况发生。
非常感谢任何帮助。
感谢。
答案 0 :(得分:0)
我已经在一个独立的程序中测试了有问题的代码片段,只需要重现所需的最少代码,并且发现问题实际上是在服务器端,即为URL提供SOAP服务的问题。到目前为止,大多数测试都适用于其他程序,但发现SOAP url在其他程序中也存在可用性问题,而不仅仅是Java,这解释了一般的问题。
用于连接和使用SOAP服务的代码没问题,问题出在目标网址上。
我仍然不知道Java控制台在尝试访问SOAP URL时在调试信息中显示不同协议的原因,但它似乎并不是一个问题(现在)。