JAX-WS Web服务客户端 - 流式传输大型附件 - 不同的行为,具体取决于JRE版本

时间:2013-01-24 00:57:41

标签: java jax-ws webservices-client

我使用已经在JRE捆绑的JAX-WS API中,从提供的WSDL-File创建了一个WebService客户端。 我使用JDK6 Update 37的 wsimport 工具生成了代理类。

客户端应该能够使用MTOM和流式传输下载大型文件/数据。

我按照Metro user guide中提供的说明进行操作。

我正在调用的代理方法返回一个DateHandler对象。

package de.christopherhuebner.webservicetest.client;                                                   

import java.io.FileOutputStream;                                                                       
import java.io.OutputStream;                                                                           
import java.net.URL;                                                                                   

import javax.activation.DataHandler;                                                                   
import javax.xml.namespace.QName;                                                                      

import de.christopherhuebner.webservicetest.ImageServer;                                               
import de.christopherhuebner.webservicetest.ImageServerService;                                        

public class ImageServiceClient {                                                                      

    public static void main(String[] args) throws Exception {                                          
        URL url = new URL("http://localhost:8080/ImageWebService?wsdl");                               
        QName qname = new QName("http://webservicetest.christopherhuebner.de/", "ImageServerService"); 
        ImageServerService is = new ImageServerService(url, qname);                                    
        MTOMFeature mtom = new MTOMFeature();
        StreamingAttachmentFeature stf = new StreamingAttachmentFeature(null, true, 4000000L);
        ImageServer port = is.getImageServerPort(mtom, stf);                                                  
        DataHandler dh = port.getImage();                                                              
        System.out.println("Java-Version: " + System.getProperty("java.version"));                     
        System.out.println("DataHandler: " + dh.getClass());                                           
        System.out.println("DataSource: " + dh.getDataSource().getClass());                            
        OutputStream out = new FileOutputStream("test.jpg");                                           
        dh.writeTo(out);                                                                               
        out.close();                                                                                   
    }                                                                                                  
}                                                                                                      

使用JRE6运行此代码时,以下输出将打印到控制台:

Java-Version: 1.6.0_37
DataHandler: class javax.activation.DataHandler
DataSource: class com.sun.istack.internal.ByteArrayDataSource

不幸的是,没有可能的流,因为ByteArrayDataSource填充在客户端内存中,当接收大于最大堆大小的数据时会导致OutOfMemoryException。当我敢按照已提及的user guide中的建议将DataHandler投射到StreamingDataHandler时,会抛出ClassCastException

使用JRE7运行客户端时,一切都很好,如user guide中所述:

Java-Version: 1.7.0_10
DataHandler: class com.sun.xml.internal.ws.encoding.MIMEPartStreamingDataHandler
DataSource: class com.sun.xml.internal.ws.encoding.MIMEPartStreamingDataHandler$StreamingDataSource

使用 JRE6 时,是否有可能获得StreamingDataHandler? 或者我真的被迫通过-Djava.endorsed.dirs=path_to_newer_jaxws_libs机制使用较新的 JAX-WS RI 版本(Metro似乎包含在JRE中)?

在流式传输期间生成的临时文件( MIMExxxxx.tmp ,请参阅StreamingAttachmentFeature进行配置)是什么时候删除?

0 个答案:

没有答案