我用Java创建了一个Web服务客户端,它使用JAXB和客户端代理成功调用Web服务,并使用MTOM发送二进制数据。
该服务现在需要SSL。更新我的客户端代码以提供SSL连接后,我可以成功调用不需要二进制附件,但需要二进制附件的调用挂起。从未收到服务的响应。最终我的客户超时了。
我怎样才能让它发挥作用?使用SSL时,是否需要执行一些特殊操作才能启用MTOM?我搜索了这个网站和网站,没有看到其他报道。
我从服务器端观看网络数据包的人那里获得了一些信息。我解释说,因为我不完全理解:他说TLS已启动并且数据传输,但随后它再次进入TLS加密握手并停止。他想知道是否为MTOM生成了单独的TLS会话,而我的应用程序认为已经建立了TLS会话,并且没有像它应该那样进行初始的证书交换。我不知道如何检查出来,因为它在低级库代码中都存在,而且我没有源代码。
我对Web服务和SSL非常非常新。
创建Web服务的代码如下:
private MyService getService() throws Exception {
SSLHelper.initializeConduitForSSL(new File("d:/keystore.jks"), "jks", "changeit");
final JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(MyService.class);
factory.setAddress("https://" + endPoint); // endpoint not shown in this code
service = (MyService)factory.create();
final Client client = ClientProxy.getClient(service);
final HTTPConduit http = (HTTPConduit)client.getConduit();
http.setTlsClientParameters(SSLHelper.getTlsParams());
final Map<String, Object> ctxt = ((BindingProvider)publishingService).getRequestContext();
// Enable HTTP chunking mode, otherwise HttpURLConnection buffers
ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192);
return service;
}
要发出请求,我会在返回的服务对象上调用方法。
SSLHelper是我自己的类,用于处理证书设置。我相信这部分不是问题,所以我不会在这里包含该设置代码。 (因为我可以使用相同的SSL配置发出其他请求,我假设这不是问题。)
对于MTOM调用,该方法接受一个参数,该参数是具有指定的字段(具有适当的setter)的请求类的实例:
@XmlElement(required = true)
@XmlMimeType("application/octet-stream")
private DataHandler dataHandler;
要初始化此课程,请执行以下操作:
File file = new File("c:\\somefile.jpg"); //
final DataSource dataSource = new FileDataSource(file);
request.setDataHandler(new DataHandler(dataSource));
DataHandler和FileDataSource位于javax.activation包中。
最后一件事。该服务的所有者能够使用MTOM成功调用此请求,但他们使用以下方法启用SSL:
System.setProperty("javax.net.ssl.keyStore", keyStorePath);
System.setProperty("javax.net.ssl.keyStoreType", "jks");
System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword);
我不能这样做,因为在同一个JVM中,我们使用多个密钥库来连接不同的Web服务。