请你帮忙。我有一个Codenameone应用程序,该应用程序向云Tomcat 8服务器发出GET请求,并期望返回一些响应JSON。重要的是,这是一个HTTPS调用。
当我在邮递员中运行请求时,它工作正常:
https://www.mydomain.co.uk:8443/MyProject/v1/generate_token
通过我的浏览器使用的URL相同,并显示为“安全”,我可以看到我的证书详细信息。我已经为我的SSL / TLS配置购买了证书,并且似乎在启动日志中可以正常运行。
在模拟器中,从URL调用读取响应时,我得到以下错误-我猜必须将其加密:
Exception: javax.net.ssl.SSLHandshakeException - sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1959) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026) at sun.security.ssl.Handshaker.process_record(Handshaker.java:961) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492) at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:347) at com.codename1.impl.javase.JavaSEPort.getResponseCode(JavaSEPort.java:7591) at com.codename1.io.ConnectionRequest.performOperation(ConnectionRequest.java:702) at com.codename1.io.NetworkManager$NetworkThread.run(NetworkManager.java:282) at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
为什么该应用程序与Postman进行呼叫有什么不同(“网络监视器”窗口确认相同的URL呼叫)?
我打电话后没有任何日志被更新,因此没有要检查的日志。从http更改为https之后,我尚未对应用程序进行任何更改(正在运行)。
这是进行呼叫的CN1代码:
public String fetchTokenIntoStorage(String userName, String password) { ConnectionRequest r = new ConnectionRequest(); r.setUrl(Constants.URL_HOST_PORT + "/MyProject" + Constants.LIVE_OR_TEST + "/v1/generate_token"); r.addRequestHeader("Content-Type", "application/json"); r.addRequestHeader("userName", userName); r.addRequestHeader("password", password); r.setHttpMethod("GET"); r.setFailSilently(false); r.setPost(false); // show spinning dialog while connecting InfiniteProgress prog = new InfiniteProgress(); Dialog dlg = prog.showInifiniteBlocking(); r.setDisposeOnCompletion(dlg); NetworkManager.getInstance().setTimeout(10000); // NetworkManager.getInstance().addErrorListener(new ActionListener() { // // @Override // public void actionPerformed(ActionEvent evt) { // MessageBox.showDialogMessage("Unable to connect to server. Please // retry later."); // } // }); // NetworkManager.getInstance().updateThreadCount(2); NetworkManager.getInstance().addToQueueAndWait(r); if (r.getResponseData() != null) { JSONParser parser = new JSONParser(); Map<String, Object> json = null; try { json = parser.parseJSON(new InputStreamReader(new ByteArrayInputStream(r.getResponseData()))); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (json.get("error") != null) { return String.valueOf(json.get("error")); } JwtRecord record = new JwtRecord(); record.userId = Integer.parseInt(String.valueOf(json.get("userId"))); record.jsonWebToken = (String) json.get("jwt"); record.theme = "LIGHT"; Storage.getInstance().writeObject("MyToken", record); return ""; } if (!r.getResponseErrorMessage().equalsIgnoreCase("")) { return r.getResponseErrorMessage(); } else { return "Unable to connect to server. Please check connection."; } }
单步执行代码之后似乎出错
NetworkManager.getInstance().addToQueueAndWait(r);
r.getResponseData()和r.getResponseErrorMessage()为空。
非常感谢
现在正在工作。
(在tomcat上)我确保根证书和中间证书在我的密钥库中(根据我之前包含的链接)。我将我的.ca-bundle很好地包含在密钥库中。
(在tomcat上)我注意到我正在使用旧版本的Apache配置(从中学到了依赖较旧的论坛帖子的经验)。需要让apache .conf文件中的SSLCACertificateFile指向我的.ca-bundle文件,而不是使用SSCertificateChainFile。
它仍然在我的模拟器上出错,但可以在我的iPhone上运行,这表明(如Shai所述)我期望的JDK不同,因此将笔记本电脑升级到了更高的JDK 1.8.171。这本身并没有改变,但可能是必需的。
通过深入研究,我意识到笔记本电脑上的模拟器也需要上述工具。因此,我最终以管理员身份在命令提示符下运行以下语句,现在我的模拟器正在运行。
cd%java_home%\ jre \ lib \ security
路径=%java_home \ bin
keytool-导入-alias comodo -keystore cacerts-文件C:\ path \ ComodoRoot.cer
keytool-导入-alias comodo_intermediate -keystore cacerts-文件C:\ path \ ComodoInter.cer
keytool-导入-别名购买_cert-密钥库cacerts-文件C:\ path \ my_purchased_cert.crt