HTML5+J2EE实现文件异步上传

P.S. HTML5经过了W3C的8年努力,终于正式推广了。这次升级最大的就是升级了XMLHTTPRequest,让它变成了XMLHTTPRequest Level II(这有啥奇怪的?)。这个对象现在非常强大,可能会让所有使用jQuery的人全部重新拾起HTML原生的ajax技术。

闲话扯到这,接着是主题:我们今天要实现的就是下面的效果:

这里面文件名、文件大小和MIME都是在选择文件时读取和现实,然后点击上传之后,上传进度实时显示,最后弹出右边的对话框确认文件信息(当然这里我为了方便直接把文件信息压到POST请求里面了,否则可能乱码,你也可以试试服务器端直接读取)。

接着,看到了这个强大的效果,我们简单地分析以下思路。

1、我们首先确定实现方式:Javascript将会显示在客户端显示进度(用的是XMLHTTPRequest Level II的几个新的Event),然后同时上传文件信息和文件本身,当然是异步的。

2、服务器端用一个servlet就行,这里使用commonfileupload接受上传。

然后看一下新的XMLHTTPRequest Level II,看看如何监视这一过程。

<input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>

选择文件这里看到了一个onchange事件,这不是一个新事件,但在HTML5标准中被重新定义了,被用于文件被选择的时候调用。

function fileSelected() { //文件选择更改时调用的事件
    var file = document.getElementById(‘fileToUpload‘).files[0]; //获得文件上传信息
    if (file) { //如果用户选择了文件(没有选择的话,file就是null或是undefined,这样可以判断)
        var fileSize = 0; //文件大小
        if (file.size > 1024 * 1024) //如果文件大小大于1MB
            fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100)
                    .toString()
                    + ‘MB‘; //转换文件大小并以MB单位显示
        else
            //否则

            fileSize = (Math.round(file.size * 100 / 1024) / 100).toString()
                    + ‘KB‘; //否则用KB单位显示
        document.getElementById(‘fileName‘).innerHTML = ‘ ‘ + file.name; //显示文件名信息
        document.getElementById(‘fileSize‘).innerHTML = ‘ ‘ + fileSize; //显示文件大小信息
        document.getElementById(‘fileType‘).innerHTML = ‘ ‘ + file.type; //显示文件MIME信息
    }
}

这个注释不是我加的,我也不清楚是谁加的……但是大家应该能看懂了。

function uploadFile() { //点击上传按钮时的时间
    var fd = new FormData(); //FormData是Html5的新增类
    fd.append("file", document.getElementById(‘fileToUpload‘).files[0]); //向表单数据添加文件主体
    var file = document.getElementById(‘fileToUpload‘).files[0]; //获得文件主体
    var xhr = new XMLHttpRequest(); //初始化ajax请求
    xhr.upload.addEventListener("progress", uploadProgress, false); //HTML5的新的事件,上传进度改变时,只能在有文件上传的情况下调用
    xhr.addEventListener("load", uploadComplete, false); //老事件,上传完成后
    xhr.addEventListener("error", uploadFailed, false); //出错时
    xhr.addEventListener("abort", uploadCanceled, false); //中断时
    var caption=document.getElementById("caption").value; //标题(和文件上传无关紧要)
    fd.append("filename", file.name); //文件名添加到表单数据
    fd.append("filesize", file.size); //文件尺寸添加到表单数据
    fd.append("filetype", file.type); //MIME添加到表单数据
    fd.append("caption", caption); //标题添加到表单数据
    xhr.open("POST", "FileUpload",true); //准备上传
    //xhr.setRequestHeader("Content-Type", "multipart/form-data"); //这句千万不能有!!!我也不知道为什么……
    xhr.send(fd); //发出请求
}

点击上传按钮之后就是这段代码,FormData也是新加的对象,用于存储表单数据(某人加的注视应该够明白了……)。

接着我们看后台,后台使用commonfileupload接收(貌似说过了……),先把代码贴出来:

package Upload;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import Log.LogManager;

public class FileUpload extends HttpServlet {

    /**
     * Constructor of the object.
     */
    public FileUpload() {
        super();
    }

    /**
     * Destruction of the servlet. <br>
     */
    public void destroy() {
        super.destroy(); // Just puts "destroy" string in log
        // Put your code here
    }

    /**
     * The doPost method of the servlet. <br>
     *
     * This method is called when a form has its tag value method equals to post.
     *
     * @param request the request send by the client to the server
     * @param response the response send by the server to the client
     * @throws ServletException if an error occurred
     * @throws IOException if an error occurred
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        try {
            request.setCharacterEncoding("UTF-8");
            DiskFileItemFactory fif=new DiskFileItemFactory();
            fif.setSizeThreshold(1024*1024);
            ServletFileUpload sfu=new ServletFileUpload(fif);
            sfu.setSizeMax(1024*1024*1024);
            List items=null;
            try {
                items=sfu.parseRequest(request);
            } catch (FileUploadException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Iterator iter=items.iterator();
            String filename="";
            String filesize="";
            String filetype="";
            String caption="";
            FileItem fi=null;
            while (iter.hasNext()) {
                FileItem item = (FileItem) iter.next();
                if (item.isFormField()) {
                    String name=item.getFieldName();
                    if(name.equals("filename")==true){
                        filename=item.getString("UTF-8");
                    }else if(name.equals("filesize")==true){
                        filesize=item.getString("UTF-8");
                    }else if(name.equals("filetype")==true){
                        filetype=item.getString("UTF-8");
                    }else if(name.equals("caption")==true){
                        caption=item.getString("UTF-8");
                    }
                } else {
                    fi=item;
                }
            }
            ServletContext application=getServletContext();
            String path=(String) application.getAttribute("datapath")+"uploadpath"+application.getAttribute("systempi")+filename;
            File f1=new File(path);
            try {
                fi.write(f1);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            response.setContentType("text/html; charset=UTF-8");
            PrintWriter out = response.getWriter();
            out.println("你上传了一个文件到服务器,下面将核实这些信息:");
            out.println("1、文件名:"+filename);
            out.println("2、文件大小:"+filesize);
            out.println("3、文件MIME类型:"+filetype);
            out.println("如果信息全部正确,说明文件成功上传了!");
            String sqls1="";
            LogManager.log("一个文件上传请求已经被受理!文件存储于:"+path);
            out.flush();
            out.close();
        } catch (Exception e) {
            LogManager.err(e.toString());
        }
    }

    /**
     * Initialization of the servlet. <br>
     *
     * @throws ServletException if an error occurs
     */
    public void init() throws ServletException {
        // Put your code here
    }

}

还挺简单的,对吗?处理HTML5的上传请求和处理以前版本的上传请求基本一样,唯一需要注意的是:原来是你来拼接请求,所以说,位置由你决定,现在FormData拼接请求的字符串中项目的顺序和append的顺序有关,所以别搞错了(貌似我就搞错了,先添加了文件,然后在后台补救了一下……)。

基本上就这些代码,然后就是添加文件信息到数据库什么的,具体上传步骤查查commonfileupload的api好了。

整个项目不方便让大家下载,但这是一个OJ项目里面的,有兴趣的关注一下进入项目的git。另外如果转载的话,注明一下,谢谢!

时间: 2024-10-13 16:24:01

HTML5+J2EE实现文件异步上传的相关文章

HTML5实现图片文件异步上传

利用HTML5的新特点做文件异步上传非常简单方便,本文主要展示JS部分,html结构.下面的代码并未使用第三发库,如果有参照,请注意一些未展现出来的代码片段.我这边的效果预览: 1.文件未选择 2.文件已选择 HTML代码部分: 思路:下面代码中我利用css的z-index属性将input="file"标签隐藏在了id=btnSelect元素下面,通过触发a标签的点击后,弹出文件选择框.下面的masklayer用于点击确认按钮后的弹出层,避免用户重复点击确认按钮. <div id

百度 flash html5自切换 多文件异步上传控件webuploader基本用法

双核浏览器下在chrome内核中使用uploadify总有302问题,也不知道如何修复,之所以喜欢360浏览器是因为帮客户控制渲染内核: 若页面需默认用极速核,增加标签:<meta name="renderer" content="webkit"> 若页面需默认用ie兼容内核,增加标签:<meta name="renderer" content="ie-comp"> 若页面需默认用ie标准内核,增加标签

使用AjaxFileUpload.js实现文件异步上传

ajax是无法提交文件的,所以在上传图片并预览的时候,我们经常使用Ifame的方法实现看似异步的效果.但是这样总不是很方便的,AjaxFilleUpload.js对上面的方法进行了一个包装,使得我们不用去管理Iframe的一系列操作,也不用影响我们的页面结构,实现异步的文件提交. html: <input type="file" name="upload" hidden="hidden" id="file_upload"

SpringMVC + AJAX 实现多文件异步上传

转自:https://www.jianshu.com/p/f3987f0f471f 今天,我就这个问题来写一篇如何用 SpringMVC + AJAX 实现的多文件异步上传功能.基本的代码还是沿用上篇文章中所用到的项目,需要的朋友可以点击前面的链接查看.在这里只贴出关键代码. 首先我们要准备一个 JS 文件,即:ajaxfileupload.js,它需要用到 jQuery,所以我们还需要准备 jQuery 的库,两个文件在文末尾都有链接提供下载. JSP 关键代码: <li> <div&

文件的上传(表单上传和ajax文件异步上传)

一.表单上传: html客户端部分: <form action="upload.ashx" method="post" enctype="multipart/form-data"> 选择文件:<input type="file" name="file1" /><br /> <input type="submit" value="上传&q

HTML5 文件异步上传 — h5uploader.js

原文地址:http://imziv.com/blog/article/read.htm?id=62 之前写过一篇H5异步文件上传的文章, 但是很多朋友看着我的这个教程还是出现很多问题,文章写的不是很好,比较早了.其实通过H5做异步上传已经非常简单了,通过查看文档,便可以很轻松的完成这个功能,当然,如果你不愿意查看文档自己动手的话,那么就用插件咯.h5uploader是我最近封装的HTML5上传插件,代码才白来行,使用的话也比较简单,支持文件大小,类型,progress等等功能.本篇教程,将向你展

使用FormData实现ajax文件异步上传

1.传统的web开发文件上传一般是基于form表单的文件上传,同步的方式,用户体验差,可控性也差 2.异步上传的实现 有以下方式 2.1 借助浏览器插件 一般需要安装一些类似flash的插件  这种方式 缺点:需要安装插件  优点:可控性强,性能高 2.2 这种是伪异步上传,借助表单向隐藏的iframe提交,然后通过iframe通信操作当前页面 这种方式可控行查,体验一般,见下面代码  2.3 借助html5 里的 FormData 对象,可实现进度控制,异步的上传方式,见代码 iframe方式

HTML5 FormData 用jquery 异步上传报错

平时做表单都是跳转提交的,但是今天要做一个ajax图片异步上传, 网上搜索了下,方法都比较老了,居然还有用flash的, 普通的表单上传通过jquery的serialize()转换成querystring后就可以直接ajax post 上传,但是碰到文件上传就不奏效了,型号html5有个方法FormData()可以实现上传, 我写的代码如下: function upThumbSubmit() { if(!window.FormData) { alert('your brower is too o

文件上传之——用SWF插件实现文件异步上传

之前提高过几篇文件上传,那些都不错.今天小编带领大家体会一种新的上传方法,及使用Flash插件实现文件上传. 使用Flash的好处就是可以解决浏览器兼容性问题.之前我写的一个快捷复制功能也是利用的Flash. 最近一直在用MVC,所以还是以MVC举例:先来张效果图: UploadIndex2.cshtml代码: @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&q