Java客户端调用SOAP服务超时,但SoapUI可正常连接求助
我之前也遇到过一模一样的情况!当SoapUI能正常调用SOAP服务,但自己用wsimport生成的Java客户端却报java.net.ConnectException: Connection timed out: connect时,大多是两者的运行环境或配置细节存在差异,下面是几个我亲测有效的排查和解决方向:
检查网络环境与代理配置差异
SoapUI可能自动使用了系统代理或者你手动配置过代理,但Java客户端默认没有开启代理。你可以尝试在Java代码中显式设置代理(如果你的网络需要的话):// HTTP代理配置 System.setProperty("http.proxyHost", "你的代理主机"); System.setProperty("http.proxyPort", "你的代理端口"); // HTTPS代理配置(如果服务是HTTPS的话) System.setProperty("https.proxyHost", "你的代理主机"); System.setProperty("https.proxyPort", "你的代理端口");另外,也有可能Java客户端所在机器的防火墙、安全组或者杀毒软件阻止了对目标服务端口的访问,而SoapUI所在机器没有这个限制。你可以在Java机器上用命令测试连通性:
telnet 你的目标域名 服务端口如果telnet不通,那大概率是网络层面的限制,需要调整防火墙规则。
验证Endpoint地址的准确性
仔细核对requestContext里的javax.xml.ws.service.endpoint.address是否完全正确:有没有拼写错误、端口号是否和SoapUI里用的一致、协议(http/https)有没有搞错?比如SoapUI调用的是https://xxx:443/xxx,但Java客户端写的是http://xxx:80/xxx,肯定会连不上。检查JAX-WS客户端的配置优先级
有时候wsimport生成的客户端会自带默认配置,可能覆盖了你手动设置的requestContext参数。你可以尝试在创建Port实例时,显式重新设置Endpoint和超时属性,确保配置生效:// 实例化你的Service类 YourSoapService service = new YourSoapService(); // 获取PortType实例 YourServicePort port = service.getYourServicePort(); // 转为BindingProvider来修改上下文 BindingProvider bindingProvider = (BindingProvider) port; // 重新设置Endpoint地址 bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "你的完整服务地址"); // 设置连接和请求超时(针对Sun的JAX-WS实现) bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.connect.timeout", 100000); bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.request.timeout", 100000);如果你用的是Apache CXF这类第三方JAX-WS实现,超时属性名会不一样,需要改成:
bindingProvider.getRequestContext().put("javax.xml.ws.client.connectionTimeout", "100000"); bindingProvider.getRequestContext().put("javax.xml.ws.client.receiveTimeout", "100000");排查DNS解析问题
有可能Java客户端所在机器无法正确解析目标服务的域名,而SoapUI所在机器的DNS解析是正常的。你可以在Java机器上ping目标域名,看返回的IP是否正确;或者直接把Endpoint地址换成IP地址试试,如果能连通,那就是DNS解析的问题,需要调整Java机器的DNS配置。
内容的提问来源于stack exchange,提问作者geco17

