从客户端调用时,jax-ws DataHandler getName()为空

时间:2012-09-03 15:12:52

标签: java download jax-ws datahandler

我在使用带有jax-ws的DataHandler时遇到了问题。当客户端调用DataHandler的getName()方法时,返回一个空字符串。 在服务器端,它被正确评估。 在这里,我报告服务器端和客户端的代码部分:

服务器侧

public @XmlMimeType("application/octet-stream") DataHandler fileDownload(String name) {
   try {
         File file = new File("/tmpwk/share/SharedRepository/apps-data/jaxws-large_upload/" + name);
         FileDataSource fds = new FileDataSource(file);
     DataHandler dh = new DataHandler(fds);
         // Note: getName(), return a String with file name.
     System.out.println("File Name = " + dh.getName() );
     System.out.println("Content Type  " + dh.getContentType());

     System.out.println("quiting from downloadFile...");    
     return dh;
    } catch(Exception e) {
        throw new WebServiceException(e);
    }

}

客户端

public void download() throws IOException {
    System.out.println(">>>>> download <<<<<<");
    MTOMFeature feature = new MTOMFeature();
    UploadImplService service = new UploadImplService();
    UploadImpl proxy = service.getUploadImplPort(feature);        
    Map<String, Object> ctxt = ((BindingProvider)proxy).getRequestContext();
    ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192); 


    DataHandler dh = proxy.fileDownload("file.bin");
    InputStream in = dh.getInputStream();

    //Note:  getName() return a empty string, why ????
            System.out.println("File Name = " + dh.getName());
    System.out.println("Content Type = " + dh.getContentType());


    File file = new File("/tmp/dfile.bin");
    OutputStream out = new FileOutputStream(file);

    // Transfer bytes from in to out
    byte[] buf = new byte[8192];
    int len;
    while ((len = in.read(buf)) > 0) {
        out.write(buf, 0, len);
    }
    in.close();
    out.close();
}

为什么会这样?

3 个答案:

答案 0 :(得分:1)

今天我遇到了同样的情况。幸运的是,我找到了原因。

如果您深入调试源代码,您会发现在JAX-WS中,DataHandler类型的参数或结果将被包装到MIMEPartStreamingDataHandler中。

MIMEPartStreamingDataHandler的dataSource是一个名为StreamingDataSource的内部类。由DataHandler定义,它的getName方法应该由它的dataSource委托。但是,StreamingDataSource的getName方法只返回一个空字符串“”。就像:

public String getName() {
    return "";
}

您可以在here处了解源代码的概述。

这个问题的一个可能的解决方案是:

  1. 为您的上传服务方法提供另一个参数以指定其名称。
  2. 使用String属性包装结果。

答案 1 :(得分:0)

我也遇到了同样的问题,但有些我如何使用StreamingDataHandler,而且我的代码也能运行。

dh=proxy.get("file.bin");   //WS CALL
if( dh!=null){          
    StreamingDataHandler sdh = (StreamingDataHandler)dh;            
    File file = new File(filePath+ File.separator +fileName);
    sdh.moveTo(file);
 }

答案 2 :(得分:0)

我有同样的问题,它让我忙了一会儿。尽管看起来很奇怪,但我终于发现文件的名称是在DataHandler对象的contentType属性中提供的!以下是如何派生文件名:

String contentType = dataHandler.getContentType();
//if you print out contentType, it is something like this:  "application/pdf; name=9ad22859-cdc9-4de5-b374-2c36acc5c253.pdf"
String fileName = (contentType.substring(contentType.indexOf("name=") + 5)).trim();

干杯!