我在发送简单的 SOAP 请求并在 java 项目中获取响应时遇到问题。
我对通过 java 执行此操作还很陌生,所以我一直在查看 this教程,因为我也在项目的其余部分使用 spring-boot。
目前我收到此错误(由于与公司相关,我确实必须删除具体信息并替换为通用字符串,以便将它们粘贴到此处。我必须删除我的实际 wsdl 和实际主机名):
[INFO] --- maven-jaxb2-plugin:0.12.3:generate (default) @ dcc-vm-validation ---
[INFO] Up-to-date check for source resources [[myWsdl, file:pom.xml]] and taret resources [[]].
[WARNING] The URI [myWsdl] seems to represent an absolute HTTP or HTTPS URL. Getting the last modification timestamp is only possible if the URL is accessible and if the server returns the [Last-Modified] header correctly. This method is not reliable and is likely to fail. In this case the last modification timestamp will be assumed to be unknown.
[ERROR] Could not retrieve the last modification timestamp for the URI [myWsdl] from the HTTP URL connection. The [Last-Modified] header was probably not set correctly.
[WARNING] Last modification of the URI [myWsdl] is not known.
[INFO] Sources are not up-to-date, XJC will be executed.
[ERROR] Error while parsing schema(s).Location [].
com.sun.istack.SAXParseException2; IOException thrown when processing "myWsdl". Exception: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching hostname found.
这是我的 pom 的“构建”部分:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.12.3</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaLanguage>WSDL</schemaLanguage>
<generatePackage>package.wsdl</generatePackage>
<schemas>
<schema>
<url>myWsdl</url>
</schema>
</schemas>
</configuration>
</plugin>
</plugins>
</build>
在对这个特定错误的含义进行一些研究后,我能够将自签名证书从 wsdl 位置(通过 Chrome)下载到我的 table 面。然后,我使用 keytool 将此特定证书添加到我的 cacerts 文件中(我确保证书别名与上面错误中的主机名匹配)。据我所知,这可以解决我的连接问题,但事实并非如此。我仍然看到与上面相同的错误,说它找不到我的主机名。
我在这里缺少什么?
或者,我还阅读了有关完全绕过证书的内容。这也是我不会反对的方法,因为我正在从事的这个项目只是内部项目,并且将位于公司内部网上。除了员工之外,任何人都无法访问它,因此安全风险基本上可以被忽略。我知道这被认为是不好的做法,但我已经阅读了风险并与我的老板讨论过,如果我们也走这条路,他也没有意见。
我找到了这个小代码片段,似乎可以完成这项工作:
static {
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new javax.net.ssl.HostnameVerifier() {
public boolean verify(String hostname, javax.net.ssl.SSLSession session) {
if (hostname.equals(myHostname)) {
return true;
}
return false;
}
});
}
但在所有示例中,我发现它从未指定过将其放置在何处。它只是说这就是您需要忽略 SSL 和自签名证书错误的原因。我应该把它放在哪里与我的代码相关,因为我试图通过 spring/jaxb 来做到这一点,有没有一种特定的方法可以做到这一点?
抱歉,长篇大论的墙!只是想在这里学习新东西:)
最佳答案
我一般不建议编译绝对URL。它使构建变得不稳定并引入像您所遇到的问题一样的问题。
更好的解决方案是在项目本地下载并存储相关资源并使用 catalog files重写 URL。
我将假设一个绝对 URL,如 http://www.my.org/wsdl/my.wsdl
。从http://www.my.org
下载资源并将其存储在src/main/resource/www.my.org
下。
然后编写一个 src/main/resources/catalog.cat
文件,如下所示:
REWRITE_SYSTEM "http://www.my.org" "www.my.org"
在插件中配置:
<configuration>
<catalog>src/main/resources/catalog.cat</catalog>
<schemaLanguage>WSDL</schemaLanguage>
<schemas>
<schema>
<url>http://www.my.org/wsdl/my.wsdl</url>
</schema>
</schemas>
</configuration>
XJC 会将您的 http://www.my.org/wsdl/my.wsdl
URL 重写为 src/main/resources/www.my.org/wsdl/my。 wsdl
.
对此有一些注意事项,例如您无法混合相对和绝对 URL,但最终这比在构建中依赖外部资源要稳定得多。您确实希望构建稳定且可重复。想象一下如果有人更新服务器上的 my.wsdl
会发生什么。
免责声明:我是 maven-jaxb2-plugin 的作者.
关于java - 通过 Java 和 IntelliJ 连接到 SOAP 服务时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39979379/