http无刷新上传功能实现(java版)

 

file.jsp


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="java.io.*"%>



<%
    //使用http协议进行上传
    request.setCharacterEncoding("utf-8");

    response.setContentType("text/html;charset=utf-8");
    char[] hchl = { 13, 10 };

    //浏览器内部构造    Content-Type: multipart/form-data; boundary=---------------------------7dc03450302
    String boundary = request.getContentType().substring(30);//相当于boundary的值

    //   ---------------------------7dc03450302   前面再累加二个  --  7dc03450302等同于new String(hchl)字节
    String field_boundary = "--" + boundary + new String(hchl);

    String last_boundary = "--" + boundary + "--" + new String(hchl);

    String _msg = "";

    //请求输入流
    ServletInputStream getdata = request.getInputStream();
    //构造字节包装流
    ByteArrayOutputStream temp = new ByteArrayOutputStream();
    //字节大小 用来缓存
    byte[] data_line = new byte[8192];
    int line_byte_count = 0;//字节初始值
    boolean found_boundary = false;
    //
    while ((line_byte_count = getdata.readLine(data_line, 0,
            data_line.length)) != -1) {//输入流字节长度不为空
        if (!found_boundary) {
            line_byte_count = getdata.readLine(data_line, 0,
                    data_line.length); //计算出内容字节长度
        }

        String temp_str = new String(data_line, 0, line_byte_count);//包装字节流转为字符串对象

        if (temp_str.indexOf("filename") != -1) {//http协议内容描述名filename存在

            if (temp_str.substring(temp_str.indexOf("filename=") + 9,
                    temp_str.lastIndexOf("\"") + 1).length() > 2) { //截取第一个filenme="D:\SchoolManageSystem.rar"的 " 到最后一个filename=""的"上传内容

                String file_name = temp_str.substring(
                        temp_str.lastIndexOf("\\") + 1,
                        temp_str.lastIndexOf("\""));//截取内容\到最后"之间的文件名,也就是文件名 : SchoolManageSystem.rar  

                line_byte_count = getdata.readLine(data_line, 0,
                        data_line.length);//输入流字节长度

                line_byte_count = getdata.readLine(data_line, 0,
                        data_line.length);

                String uri = "E:\\xx\\upload\\";

                File file = new File(uri);
                if (file.exists()) {
                    file.delete();
                } else {
                    file.mkdirs();
                }

                FileOutputStream myfile = new FileOutputStream(uri
                        + file_name, false); //输出流对象

                boolean test = true;

                while (test) {//循环字节输出流
                    line_byte_count = getdata.readLine(data_line, 0,
                            data_line.length);
                    if (line_byte_count == -1) {
                        test = false;
                        break;
                    }
                    if (temp.size() == 0) {
                        temp.write(data_line, 0, line_byte_count);//写入字节包装流
                    } else {

                        if (new String(data_line, 0, line_byte_count)
                                .equals(field_boundary)
                                || new String(data_line, 0,
                                        line_byte_count)
                                        .equals(last_boundary)) //初始boundary长度与截取的字符串包装流长度比较 和 末尾boundary=-----------------------------7dc148550302--长度与截取的字符串包装流长度比较
                        {

                            myfile.write(temp.toByteArray(), 0,
                                    temp.toByteArray().length - 2);//想一想这里的长度为什么要-2
                                    
                            temp.reset();//清空为0
                            myfile.close();
                            //out.println(file_name+"�ϴ��ɹ��� <br>");
                            _msg = _msg + file_name + "上传成功了<br>";
                            test = false;
                            found_boundary = true;
                        } else {
                            temp.writeTo(myfile);
                            temp.reset();
                            temp.write(data_line, 0, line_byte_count);
                        }
                    }
                }
            } else {
                String field_name = temp_str.substring(
                        temp_str.indexOf("name") + 6,
                        temp_str.lastIndexOf(";") - 1); //截取name=filename
                
                
                line_byte_count = getdata.readLine(data_line, 0,
                        data_line.length);
                line_byte_count = getdata.readLine(data_line, 0,
                        data_line.length);
                line_byte_count = getdata.readLine(data_line, 0,
                        data_line.length);
                line_byte_count = getdata.readLine(data_line, 0,
                        data_line.length);
                found_boundary = true;
                // out.println(field_name+"û��ѡ���ϴ��ļ��� <br>");
                // _msg=_msg+field_name+"û��ѡ���ϴ��ļ�<br>";
            }
        } else {
            String field_name = temp_str.substring(
                    temp_str.indexOf("name") + 6,
                    temp_str.lastIndexOf("\""));
            line_byte_count = getdata.readLine(data_line, 0,
                    data_line.length);
            temp.reset();
            boolean test = true;
            while (test) {
                line_byte_count = getdata.readLine(data_line, 0,
                        data_line.length);
                if (line_byte_count == -1) {
                    test = false;
                    break;
                }
                if (new String(data_line, 0, line_byte_count)
                        .equals(field_boundary)
                        || new String(data_line, 0, line_byte_count)
                                .equals(last_boundary)) {
                    test = false;
                    found_boundary = true;
                    if (temp.size() > 2) {
                        // out.println(field_name+":"+new String(temp.toByteArray())+" <br>");
                        _msg = _msg + field_name + ":"
                                + new String(temp.toByteArray())
                                + "<br>";
                    } else {
                        // out.println(field_name+"û�����ݣ� <br>");
                        _msg = _msg + field_name + "没有内容!<br>";
                    }
                    temp.reset();
                } else {
                    temp.write(data_line, 0, line_byte_count);
                }
            }
        }

    }

    getdata.close();

    out.println("<script>window.parent.Finish('" + _msg + " "
            + field_boundary + "');</script>");
%>

 

index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>index.html</title>
    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
 
  <body>
        <style>
.fu_list {
    width: 600px;
    background: #ebebeb;
    font-size: 12px;
}

.fu_list td {
    padding: 5px;
    line-height: 20px;
    background-color: #fff;
}

.fu_list table {
    width: 100%;
    border: 1px solid #ebebeb;
}

.fu_list thead td {
    background-color: #f4f4f4;
}

.fu_list b {
    font-size: 14px;
}

/*file容器样式*/
a.files {
    width: 90px;
    height: 30px;
    overflow: hidden;
    display: block;
    border: 1px solid #BEBEBE;
    background: url(img/fu_btn.gif) left top no-repeat;
    text-decoration: none;
}

a.files:hover {
    background-color: #FFFFEE;
    background-position: 0 -30px;
}

/*file设为透明,并覆盖整个触发面*/
a.files input {
    margin-left: -350px;
    font-size: 30px;
    cursor: pointer;
    filter: alpha(opacity = 0);
    opacity: 0;
}

/*取消点击时的虚线框*/
a.files,a.files input {
    outline: none; /*ff*/
    hide-focus: expression(this.hideFocus = true); /*ie*/
}
</style>
        <form id="uploadForm" action="file.jsp">
            <table border="0" cellspacing="1" class="fu_list">
                <thead>
                    <tr>
                        <td colspan="2">
                            <b>上传文件</b>
                        </td>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td align="right" width="15%" style="line-height: 35px;">
                            添加文件:
                        </td>
                        <td>
                            <a href="javascript:void(0);" class="files" id="idFile"></a>
                            <img id="idProcess" style="display: none;" src="img/loading.gif" />
                        </td>
                    </tr>
                    <tr>
                        <td colspan="2">
                            <table border="0" cellspacing="0">
                                <thead>
                                    <tr>
                                        <td>
                                            文件路径
                                        </td>
                                        <td width="100"></td>
                                    </tr>
                                </thead>
                                <tbody id="idFileList">
                                </tbody>
                            </table>
                        </td>
                    </tr>
                    <tr>
                        <td colspan="2" style="color: gray">
                            温馨提示:最多可同时上传
                            <b id="idLimit"></b> 个文件,只允许上传
                            <b id="idExt"></b> 文件。
                        </td>
                    </tr>
                    <tr>
                        <td colspan="2" align="center" id="idMsg">
                            <input type="button" value="开始上传" id="idBtnupload"
                                disabled="disabled" />
                            &nbsp;&nbsp;&nbsp;
                            <input type="button" value="全部取消" id="idBtndel"
                                disabled="disabled" />
                        </td>
                    </tr>
                </tbody>
            </table>
        </form>
        <script type="text/javascript">
    var isIE = (document.all) ? true : false;

    var $ = function(id) {
        return "string" == typeof id ? document.getElementById(id) : id;
    };

    var Class = {
        create : function() {
            return function() {
                this.initialize.apply(this, arguments);
            }
        }
    }

    var Extend = function(destination, source) {
        for ( var property in source) {
            destination[property] = source[property];
        }
    }

    var Bind = function(object, fun) {
        return function() {
            return fun.apply(object, arguments);
        }
    }

    var Each = function(list, fun) {
        for ( var i = 0, len = list.length; i < len; i++) {
            fun(list[i], i);
        }
    };

    //文件上传类
    var FileUpload = Class.create();
    FileUpload.prototype = {
        //表单对象,文件控件存放空间
        initialize : function(form, folder, options) {

            this.Form = $(form);//表单
            this.Folder = $(folder);//文件控件存放空间
            this.Files = [];//文件集合

            this.SetOptions(options);

            this.FileName = this.options.FileName;
            this._FrameName = this.options.FrameName;
            this.Limit = this.options.Limit;
            this.Distinct = !!this.options.Distinct;
            this.ExtIn = this.options.ExtIn;
            this.ExtOut = this.options.ExtOut;

            this.onIniFile = this.options.onIniFile;
            this.onEmpty = this.options.onEmpty;
            this.onNotExtIn = this.options.onNotExtIn;
            this.onExtOut = this.options.onExtOut;
            this.onLimite = this.options.onLimite;
            this.onSame = this.options.onSame;
            this.onFail = this.options.onFail;
            this.onIni = this.options.onIni;

            if (!this._FrameName) {
                //为每个实例创建不同的iframe
                this._FrameName = "uploadFrame_"
                        + Math.floor(Math.random() * 1000);
                //ie不能修改iframe的name
                var oFrame = isIE ? document.createElement("<iframe name=\""
                        + this._FrameName + "\">") : document
                        .createElement("iframe");
                //为ff设置name
                oFrame.name = this._FrameName;
                oFrame.style.display = "none";
                //在ie文档未加载完用appendChild会报错
                document.body.insertBefore(oFrame, document.body.childNodes[0]);
            }

            //设置form属性,关键是target要指向iframe
            this.Form.target = this._FrameName;
            this.Form.method = "post";
            //注意ie的form没有enctype属性,要用encoding
            this.Form.encoding = "multipart/form-data";

            //整理一次
            this.Ini();
        },
        //设置默认属性
        SetOptions : function(options) {
            this.options = {//默认值
                FileName : "filename",//文件上传控件的name,配合后台使用
                FrameName : "",//iframe的name,要自定义iframe的话这里设置name
                onIniFile : function() {
                },//整理文件时执行(其中参数是file对象)
                onEmpty : function() {
                },//文件空值时执行
                Limit : 10,//文件数限制,0为不限制
                onLimite : function() {
                },//超过文件数限制时执行
                Distinct : true,//是否不允许相同文件
                onSame : function() {
                },//有相同文件时执行
                ExtIn : [ "gif", "jpg", "rar", "zip", "iso", "swf" ],//允许后缀名
                onNotExtIn : function() {
                },//不是允许后缀名时执行
                ExtOut : [],//禁止后缀名,当设置了ExtIn则ExtOut无效
                onExtOut : function() {
                },//是禁止后缀名时执行
                onFail : function() {
                },//文件不通过检测时执行(其中参数是file对象)
                onIni : function() {
                }//重置时执行
            };
            Extend(this.options, options || {});
        },
        //整理空间
        Ini : function() {
            //整理文件集合
            this.Files = [];
            //整理文件空间,把有值的file放入文件集合
            Each(this.Folder.getElementsByTagName("input"), Bind(this,
                    function(o) {
                        if (o.type == "file") {
                            o.value && this.Files.push(o);
                            this.onIniFile(o);
                        }
                    }))
            //插入一个新的file
            var file = document.createElement("input");
            file.name = this.FileName;
            file.type = "file";
            file.onchange = Bind(this, function() {
                this.Check(file);
                this.Ini();
            });
            this.Folder.appendChild(file);
            //执行附加程序
            this.onIni();
        },
        //检测file对象
        Check : function(file) {
            //检测变量
            var bCheck = true;
            //空值、文件数限制、后缀名、相同文件检测
            if (!file.value) {
                bCheck = false;
                this.onEmpty();
            } else if (this.Limit && this.Files.length >= this.Limit) {
                bCheck = false;
                this.onLimite();
            } else if (!!this.ExtIn.length
                    && !RegExp("\.(" + this.ExtIn.join("|") + ")$", "i").test(
                            file.value)) {
                //检测是否允许后缀名
                bCheck = false;
                this.onNotExtIn();
            } else if (!!this.ExtOut.length
                    && RegExp("\.(" + this.ExtOut.join("|") + ")$", "i").test(
                            file.value)) {
                //检测是否禁止后缀名
                bCheck = false;
                this.onExtOut();
            } else if (!!this.Distinct) {
                Each(this.Files, function(o) {
                    if (o.value == file.value) {
                        bCheck = false;
                    }
                })
                if (!bCheck) {
                    this.onSame();
                }
            }
            //没有通过检测
            !bCheck && this.onFail(file);
        },
        //删除指定file
        Delete : function(file) {
            //移除指定file
            this.Folder.removeChild(file);
            this.Ini();
        },
        //删除全部file
        Clear : function() {
            //清空文件空间
            Each(this.Files, Bind(this, function(o) {
                this.Folder.removeChild(o);
            }));
            this.Ini();
        }
    }

    var fu = new FileUpload(
            "uploadForm",
            "idFile",
            {
                onIniFile : function(file) {
                    file.value ? file.style.display = "none" : this.Folder
                            .removeChild(file);
                },
                onEmpty : function() {
                    alert("请选择一个文件");
                },
                onLimite : function() {
                    alert("超过上传限制");
                },
                onSame : function() {
                    alert("已经有相同文件");
                },
                onNotExtIn : function() {
                    alert("只允许上传" + this.ExtIn.join(",") + "文件");
                },
                onFail : function(file) {
                    this.Folder.removeChild(file);
                },
                onIni : function() {
                    //显示文件列表
                    var arrRows = [];
                    if (this.Files.length) {
                        var oThis = this;
                        Each(this.Files, function(o) {
                            var a = document.createElement("a");
                            a.innerHTML = "取消";
                            a.href = "javascript:void(0);";
                            a.onclick = function() {
                                oThis.Delete(o);
                                return false;
                            };
                            arrRows.push( [ o.value, a ]);
                        });
                    } else {
                        arrRows.push( [ "<font color='gray'>没有添加文件</font>",
                                "&nbsp;" ]);
                    }
                    AddList(arrRows);
                    //设置按钮
                    $("idBtnupload").disabled = $("idBtndel").disabled = this.Files.length <= 0;
                }
            });

    $("idBtnupload").onclick = function() {
        //显示文件列表
        var arrRows = [];
        Each(fu.Files, function(o) {
            arrRows.push( [ o.value, "&nbsp;" ]);
        });
        AddList(arrRows);

        fu.Folder.style.display = "none";
        $("idProcess").style.display = "";
        $("idMsg").innerHTML = "正在添加文件到您的网盘中,请稍候……<br />有可能因为网络问题,出现程序长时间无响应,请点击“<a href='?'><font color='red'>取消</font></a>”重新上传文件";

        fu.Form.submit();
    }

    //用来添加文件列表的函数
    function AddList(rows) {
        //根据数组来添加列表
        var FileList = $("idFileList"), oFragment = document
                .createDocumentFragment();
        //用文档碎片保存列表
        Each(rows, function(cells) {
            var row = document.createElement("tr");
            Each(cells, function(o) {
                var cell = document.createElement("td");
                if (typeof o == "string") {
                    cell.innerHTML = o;
                } else {
                    cell.appendChild(o);
                }
                row.appendChild(cell);
            });
            oFragment.appendChild(row);
        })
        //ie的table不支持innerHTML所以这样清空table
        while (FileList.hasChildNodes()) {
            FileList.removeChild(FileList.firstChild);
        }
        FileList.appendChild(oFragment);
    }

    $("idLimit").innerHTML = fu.Limit;

    $("idExt").innerHTML = fu.ExtIn.join(",");

    $("idBtndel").onclick = function() {
        fu.Clear();
    }

    //在后台通过window.parent来访问主页面的函数
    function Finish(msg) {
        msg = msg.replace(/<br[^>]*>/ig, "\n").replace(/&nbsp;/ig, "   ");
        alert(msg);
        location.href = location.href;
    }
</script>
    </body>
</html>

 

 

posted @ 2012-03-04 09:18  南洋小学生  Views(588)  Comments(0)    收藏  举报