`
hardneedl
  • 浏览: 31568 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

java web service 大文件上传/下载 DataHandler

阅读更多

传输小体积文件(不超过10M)通常采用byte[]来容纳数据内容。开发过程中,通常是以下面给出的代码形式来定义数据类型:

 


public byte[] download(String fileName);

public void upload(String fileName, byte[] content);

 

 

数据内容即以byte[]的方式来容纳。毕竟字节数组的长度是有限的,大体积的数据流显然不适合用如此方式操作。webservice规范中指出:二进制内容在网络传输过程中还能以soap附件的形式收发。

 

 

本文将要涉及到的内容是:

 

     使用sun webservices 参考实现版本作为开发和运行环境

    通过Webservice上载或下载大体积的文件(至少是500M以上)。

    采用annotation的注解方式开启webservice的消息传输优化。

    使用DataHandler操作输入输出流。

 

知识点


Webservice 通过“附件”的形式可把多个二进制内容粘贴到消息的附件部位上。因此在编程的过程中既可以直接操纵webservice的原始消息内容(使用soap的消 息操作API)进行“附件”的读写也能使用客户端存根代码的java代理类进行操作。Web service规范中的一项: MTOM (Message Transmission and Optimization Mechanism)即是进行此项操作的用场。


 

数据内容和JAVA的数据类型



下表列举了在http传输过程中媒体内容的类型和JAVA编程对象的对应关系

MIME Type

Java Type

image/gif

java.awt.Image

image/jpeg

java.awt.Image

text/plain

java.lang.String

text/xml or application/xml

javax.xml.transform.Source

*/*

javax.activation.DataHandler

 


以图片的内容来解释下传输类型的转换过程:

java.awt.Image类型的对象在传输前按照image/gif;image/jpeg的编码规则(HTTP上媒体字节内容的编码规则)进行编码,而后写到soap消息中;从soap消息里还原出媒体内容的时候即还原成java.awt.Image的对象实例。

 

*/*这种类型就是“通吃”了,完全依靠DataHandler的实现提供输入输出流来操作媒体内容。这种类型就是本文要采用的。

 

代码讲解

先来看上载文件的服务端。webservice的实现类用annotation标注以开启MTOM方式

@javax.xml.ws.soap.MTOM

public class MTOMServer {

...

}

 

上载的功能

public void upload(

        @WebParam(name="fileName")String fileName,

 

         @XmlMimeType("*/*")

        @WebParam(name="fileDataHandler")

        DataHandler dataHandler)throws IOException

 

用DataHandler充当上载的数据操作的“手柄”,并且明确地使用  @XmlMimeType("*/*")标注以表示采用数据流的方式把媒体内容写到SOAP消息的附件部位。(如果不明确地进行标记,那么客户端存根代码上就不会出现DataHandler,而是byte[])。

 

下载的功能

@WebResult

@XmlMimeType("*/*")

public DataHandler download(

        @WebParam(name="fileName")String fileName

)throws FileNotFoundException{

同样显示地标注*/*表示客户端将得到DataHandler(如果不明确地进行标记,那么客户端存根代码上就不会出现DataHandler,而是byte[])

 


 

客户端也能开启MTOM。开启的方式可以在获取服务的时候指出:

public MTOMServerService getMTOMServer(WebServiceFeature... features) 

实参用MTOMFeature的实例。

 

客户端调用上载方法前还需为请求的上下文环境指定“流操作的块的大小”

Map<String, Object> ctxt = ((BindingProvider)mtomPort).getRequestContext();

ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 2048);

 

 

以下贴出服务端代码


package mtom;
import javax.jws.*;
import javax.xml.bind.annotation.*;
import javax.xml.ws.*;
import javax.activation.*;
import javax.annotation.*;
import java.io.*;
import java.util.*;
/**
 * @author Hardneedl
 */
@javax.xml.ws.soap.MTOM
@WebService(name="MTOMServerService",portName="MTOMServer")
public class MTOMServer {
    private static final int BUFFER_SIZE = 1024*1024*20;
    @Resource
    private WebServiceContext serviceContext;
    /**
     * 下载文件
     * @return 数据句柄
     */
    @WebResult
    @XmlMimeType("*/*")
    public DataHandler download(
        @WebParam(name="fileName")String fileName)throws FileNotFoundException{
        if (fileName==null||fileName.isEmpty())
            throw new FileNotFoundException("file name is empty");

        File dir = getFileDepository();
        File downloadFile = new File(dir.getAbsolutePath()+File.separatorChar+fileName);
        if (!downloadFile.exists())
            throw new FileNotFoundException(fileName + " does not exist");

        return new DataHandler(
            new FileDataSource(downloadFile){
                public String getContentType() {
                    return "application/octet-stream";
                }
            }
        );
    }

    @WebResult
    @XmlMimeType("*/*")
    public DataHandler[] downloadMulti()throws FileNotFoundException{
        final File[] files = getFileDepository().listFiles();
        DataHandler[] handlers = new DataHandler[files.length];

        for (int i = 0,j=files.length; i < j; i++){
            final String fileName = files[i].getName();
            handlers[i]=
                new DataHandler(new FileDataSource(files[i])){
                    public String getName() {return fileName;}
                };
        }
        return handlers;
    }


    /**
     * 上载
     * @param fileName 待上载的文件名
     * @param dataHandler 数据句柄
     * @throws IOException IO异常
     */
    public void upload(
        @WebParam(name="fileName")String fileName,

        @XmlMimeType("*/*")
        @WebParam(name="fileDataHandler")
        DataHandler dataHandler)throws IOException{

        File depository = getFileDepository();

        InputStream in = dataHandler.getInputStream();
        OutputStream out = new FileOutputStream(depository.getAbsolutePath()+File.separatorChar+fileName);

        byte[] buf = new byte[BUFFER_SIZE];
        int read;
        while( (read=in.read(buf))!=-1 ) {
            out.write(buf,0,read);
            out.flush();
        }
        in.close();
        out.close();
    }

    /**
     * 列表文件清单
      * @return 文件清单
     */
    public java.util.List<FileDescription> listFiles(){
        File fileDepository = getFileDepository();
        java.util.List<FileDescription>L=new java.util.ArrayList<FileDescription>(0);

        for (File f : fileDepository.listFiles()) {

            FileDescription fds = new FileDescription();


            Calendar cal = Calendar.getInstance();
            cal.setTimeInMillis(f.lastModified());

            fds.setModifiedDate(cal);
            fds.setFileName(f.getName());
            fds.setLength(f.length());
            L.add(fds);
        }

        return L;
    }

    /**
     * 获取临时上载文件的路径
     * @return 临时文件路径
     */
    private static File getFileDepository(){
        return new File(System.getProperty("java.io.tmpdir"));
    }
}
 

客户端代码

import stub.*;
import javax.xml.namespace.*;
import javax.xml.ws.soap.*;
import javax.xml.ws.*;
import javax.activation.*;
import java.net.*;
import java.util.*;
import java.text.*;
import java.io.*;
import java.io.IOException;
import com.sun.xml.ws.developer.*;
/**
 * @author Hardneedl
 */
class FileClient {
    final static private int CHUNK_SIZE = 1024*1024*300;
    final static private SimpleDateFormat DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    public static void main(String[] args) throws MalformedURLException, IOException_Exception {

        URL url = new URL(args[0]);
        QName qname = new QName("http://mtom/", "MTOMServerService");
        MTOMServerService_Service service = new MTOMServerService_Service(url,qname);

        MTOMFeature feature = new MTOMFeature();
        MTOMServerService mtomPort = service.getMTOMServer(feature);

        //列文件清单
        for(FileDescription fds : mtomPort.listFiles()){
            System.out.println("file Name : "+fds.getFileName());
            System.out.println("file size : "+fds.getLength());

            Date date = fds.getModifiedDate().toGregorianCalendar().getTime();
            System.out.println("last date : "+ DATEFORMAT.format(date));
            System.out.println("___________________________________________");
        }


        //上载文件
        if(args.length<2){
            System.err.println("no file to be upload.");
            System.err.println("set the file path on the command line for the second argument\ne.g\nFileClient [wsdl-url] [full path]");
        }
        else{
            Map<String, Object> ctxt = ((BindingProvider)mtomPort).getRequestContext();
            ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, CHUNK_SIZE);
            File uploadFile = new File(args[1]);
            FileDataSource fileDataSource = new FileDataSource(uploadFile);
            DataHandler dataHandler = new DataHandler(fileDataSource);
            mtomPort.upload(uploadFile.getName(),dataHandler);
        }

        //下载指定的单个文件
        //try {
        //    final String fileName = "深海圆疑.rmvb";
        //    OutputStream fileOut = new FileOutputStream(fileName);
        //
        //    DataHandler downloadHandler = mtomPort.download(fileName);
        //    InputStream fileIn = downloadHandler.getInputStream();
        //    byte[] buf = new byte[CHUNK_SIZE];
        //    int read;
        //    while (-1 != (read = fileIn.read(buf))) {
        //        fileOut.write(buf,0,read);
        //        fileOut.flush();
        //    }
        //    fileIn.close();
        //    fileOut.close();
        //} catch(FileNotFoundException_Exception e) {
        //    e.printStackTrace();
        //} catch(IOException e) {
        //    e.printStackTrace();
        //}

        //下载全部文件
        try {
            List<DataHandler> dataHandlers = mtomPort.downloadMulti();
            byte[] buf = new byte[CHUNK_SIZE];
            for (int i = 0,j=dataHandlers.size(); i <j;i++) {
                DataHandler handler = dataHandlers.get(i);
                String fileName = handler.getName();
                fileName = fileName==null||fileName.isEmpty()?Integer.toString(i):fileName;
                InputStream in = handler.getInputStream();
                OutputStream out=new FileOutputStream(fileName);

                int read;
                while((read=in.read(buf))!=-1){
                    out.write(buf,0,read);
                    out.flush();
                }
                in.close();out.close();

            }
        } catch(FileNotFoundException_Exception e) {
            e.printStackTrace();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}
分享到:
评论
6 楼 yzqnow1234 2012-08-30  
需要demo呀
5 楼 yoin528 2012-08-20  
应该是在网上拷的才写得那么简略。。。
4 楼 zjc198805 2012-04-26  
LZ,要写就写好一点的,上传个demo啥的,这个什么都没有,包都不知道如何导入的!唉...
3 楼 zjutsoft 2009-09-25  
还有包和类的。都不写清楚。
2 楼 zjutsoft 2009-09-21  
代码有错误的
1 楼 zjutsoft 2009-09-21  
不能运行啊!

相关推荐

    javaweb service大文件上传下载 DataHandler.docx

    javaweb service大文件上传下载 DataHandler

    datahandler.rar

    业务代码解耦方案与案例源码,类似于BeanUtils.copyProperties工具,不仅能进行相同字段名相同类型的字段值复制,还能进行不同类型或字段的转换

    java自动发邮件

    DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"&gt; &lt;web-app&gt; &lt;servlet-name&gt;mailsenderservlet&lt;/servlet-name&gt;&lt;!--邮件发送程序--...

    利用Java发送邮件(含附件)的例子

    emailsmtp=smtp.qq.comemailaddress=459104018@qq.comemailpass=******2、读取配置文件的类文件(ReadPropertity.java) import java.io.IOException;import java.util.Properties;public class ReadPropertity { ...

    JAVA发送邮件开源代码

    import java.util.Properties; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.Message;...//PS:把java发送邮件的导入的JAR包上传了,解压后导入你的项目里就可

    复杂邮件程序完整Java源码,支持添加附件,图片,HTML格式文本,支持远程WebService调用

    DataHandler htmlDh = new DataHandler(htmlDs); // DataHandler // 文件包装数据类 htmlPart.setDataHandler(htmlDh); // htmlPart.setContent(htmlContent,"text/html;charset=gbk"); // } // 添加图片域信息 if ...

    发送邮件的Java代码

    // 可以从配置文件读取相应的参数 Properties props = new Properties(); String smtp = "smtp.qq.com"; // 设置发送邮件所用到的smtp String servername = "401171674"; String serverpaswd = "heziyu222"; ...

    mail.jar包和activation.jar包

    创建Web Service Client 调用 Web Service时报错 Unable to find required classes (javax.activation.DataHandler and javax.ma il.internet.MimeMultipart). Attachment support is disabled. 为解决这个问题,需...

    Java调用SMTP发送邮件

    JAVA通过SMTP服务发送邮件,部分代码: import java.io.*; import java.net.URL; import java.util.Date; import java.util.Properties; import javax.activation.DataHandler; import javax.activation....

    Java邮件开发Fundamentals of the JavaMail API

    communicate with your company or Internet Service Provider's (ISP's) SMTP server. That SMTP server will relay the message on to the SMTP server of the recipient(s) to eventually be acquired by the ...

    Axis1.4从服务端到客户端图文攻略(附赠Axis1.4 Jar包)

    Axis1.4从服务端到客户端图文攻略,同时附赠Axis1.4 Jar包。 本攻略经过多次测试可靠耐用,并同时带有详细的文字说明,保证一学就会!从现在起axis不再是问题!让你爱上web service!

    开源Silverlight数据访问组件System.Data.Silverlight

    Web服务器端的文件,需要把该文件拷贝到网站根目录。 2.2同步方式操作数据库示例 //创建一个数据连接 DbConnection conn = new DbConnection("Server=192.168.0.7;DataBase=JitonClient;Uid=sa;Pwd=jiton;"); //...

    zk8-datahandler-demo

    zk8-datahandler-demo ZK8:简单但功能强大,使用数据处理程序API与前端技术一起使用## Article在看一下文章##许可证演示代码

    j2ee中英文对照版api

    public void setCommandContext(String verb, DataHandler dh) throws java.io.IOException 用请求处理的动词和描述将要操作的数据的 DataHandler 来初始化 Command。注:调用者为 DataHandler 传递 null 值是可以...

    Android mail开发依赖jar包

    Android中使用java mail发邮件时出现Could not find class 'javax.activation.DataHandler' 加入压缩包中的jar到lib文件夹即可 http://blog.csdn.net/weizi4332/article/details/21395661

    HTTP多路复用器Bone.zip

    Bone 是一个轻量级、非常... mux.Post("/data", DataHandler)  // Handle take http.Handler  mux.Handle("/", http.HandlerFunc(RootHandler))  http.ListenAndServe(":8080", mux) } 标签:Bone

    webservice实例 CXF的JAXWS和JAXRS实现 及JAXB标准接口实现带jar包

    webservice实例 CXF的JAXWS和JAXRS实现 及JAXB标准接口实现带jar包 全部手写,保证质量,导入就可以用

    android实现自动发送邮件

    本文实例为大家分享了实现了一个android自动发送邮件的demo。支持163,qq邮箱 ...import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.Address; import java

    seahawks-csl-crawler:在有人负担得起的价格时,爬行“海鹰”宪章座位执照(CSL)市场并发送短信

    海鹰CSL履带 在有人负担得起的价格时,爬行“海鹰”宪章座位执照(CSL)市场并发送短信 ... 在DataHandler.java中,设置首选部分,最高价和座位数。 在SeahawksCSLCrawler.java中,设置电话号码。

Global site tag (gtag.js) - Google Analytics