让美的事情发生
Ziv 小威
fileloder.js+struts2 实现文件异步上传,无页面刷新效果。

一、前言

  之前在写一个 web 的文件上传的功能时,希望在 web 前端对文件的大小,及类型用 js 给验证掉,然后提交到服务器保存入数据库,同时要求达到页面无刷新的异步效果。在网上也看到有很多用 iframe 的方式实现了这样的无刷新效果。不过我在这里给大家介绍的是一款 js 插件,非常强大。在用这款插件前,在网上查询了好久关于 js 对文件类型的验证,当然这样的方法很多,大多数通过正则表达式对文件后缀验证的方式,只不过对文件大小验证这项功能上网上贴出的大多数代码都不靠谱,很多浏览器根本就不支持很多属性操作,比喻说 filesize 这项,而且浏览器的兼容性上考虑起来非常麻烦。不过所幸后来我找到了 fileloader.js 这个插件,前身好像是 ajaxfileupload.js,这款插件可通过 js 提交验证文件的大小及类型、支持拖拽上传。有时间把它的源码研究下也跟大家分享下。fileloader.js 官方地址是:«http://fineuploader.com/>。当然上面也有很多 DEMO>,大家可以自己去看。

二、工作准备

  添加 strut2 框架;将下载的 fileloader.js 的文件添加到页面;将 fileloader.css 文件添加到页面;添加 jquery 包。

三、HTML 页面代码


<html>

<head>

<title>文件上传</title>

<link href="css/fileuploader.css" rel="stylesheet" type="text/css" />

  <script language="javascript" type="text/javascript" src="js/jquery-1.8.0.js"></script>

  <script language="javascript" type="text/javascript" src="js/fileuploader.js"></script>
  <script language="javascript" type="text/javascript">

    $(document).ready(function() {
        var thumbnailuploader = new qq.FileUploader({      //new fileuploader object
          element: $('#thumbnail-fine-uploader')[0],      //选定页面div元素,这里用了jquery的选择器
          action: 'service/uploadImage',            //提交的action地址
          debug: true,
          multiple: false,
          allowedExtensions: ['jpeg', 'jpg', 'gif', 'png'],  //允许上传的文件类型
          sizeLimit: 500*1024,                //允许上传文件的大小,这里是500KB,500kb = 500*1024KB
          uploadButtonText:'图片上传',            //在页面显示上传按钮
          inputName: 'myFile',                //在input标签中的name属性设置为myFile
          messages:{                     //设置的提示信息,包括大小类型等的操作
              typeError:'只允许jpeg,jpg,gif,png格式的图片文件{file}',
              sizeError:'文件大小不能超过{sizeLimit}。{file}',
              emptyError:'文件不可为空{file}',
              onLeave:'文件正在上传,离开将终止上传操作?'
          },
          showMessage:function(message){          //显示信息
            alert(message);
          },
             // 设置返回从服务器反馈的error信息,不过我这里利用这个responseProperty属性反馈msg信息,
             // 具体的msg内容在服务中设置。
          failedUploadTextDisplay: {
            mode: 'custom',
            maxChars: 40,
            responseProperty: 'msg',
            enableTooltip: true
        }

       });
    })  

  </scripte>

</head>

<body>

     <fieldset>
           <legend><span>您可以上传一张不超过500kb的图片</span></legend>
            <div>
                   <div id="thumbnail-fine-uploader"></div>  
             </div>
    </fieldset>

</body>

</html>

三、Action 服务器端代码

提示:我在项目中使用了 S2SH 框架,所以注意下自己写代码时候的区别。

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import org.hibernate.Hibernate;

import com.byg.entity.TableMsgService;
import com.byg.service.SendMessageService;

public class FileHandleAction extends SessionAction{

    private SendMessageService service;

    public void setService(SendMessageService service) {
        this.service = service;
    }
    // myFile属性,即刚才在声明fileuploader 对象时候设置的myFile属性。通过此属性接收file的Name
    private String myFile;

    public String getMyFile() {
        return myFile;
    }
    public void setMyFile(String myFile) {
        this.myFile = myFile;
    }
    // 用于返回json数据,即在刚才在fileuploader对象中的failedUploadTextDisplay
    // 中设置的responseProperty属性,显示msg的信息
    private String msg;

    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    //check file size
    /**
     * upload image
     */
    public String uploadImage(){
        //声明request对象用于获取文件流
        HttpServletRequest request = ServletActionContext.getRequest();

        if(this.getMyFile()!=null){        //如果图片名不为空

            File myFile = new File(this.getMyFile());  //用改文件名new 一个文件对象

            try {
                    InputStream is = request.getInputStream();    //获取文件流
                    FileOutputStream fout = new FileOutputStream(myFile);//定义文件输出流

                    byte b[] = new byte[1000];

                    int n ;
                    //从inputStream中把获取的文件流写入这个新new的文件对象中
                    while((n=is.read(b))!=-1){

                        fout.write(b,0,n);
                    }
                    is.close();
                    fout.flush();
                    fout.close();
                    // 我的Image对象的定义是Blob类型,所以这里我通过进一步的转化myFile
                    FileInputStream in = new FileInputStream(myFile);
                    TableMsgService msgService = new TableMsgService();
                    //通过Hibernate的createBlob方法转化,然后设置我的image属性
                    msgService.setImage(Hibernate.createBlob(in));
                    //最后保存包含这个Blob类型数据的对象,用的Hibernate框架  
                    service.save(msgService);    //save this object;

                    msg = "文件"+this.getMyFile()+"上传成功"; // msg 设置显示成功

            }catch(Exception e) {
                msg = "文件"+this.getMyFile()+"上传失败"; //如果异常 设置msg显示失败
                e.printStackTrace();
            }
        }

        return "succ";

    }
}

三、Struts.xml 的配置


<struts>
    <constant name="struts.il8n.encoding" value="utf-8"></constant>

    <package name="test" extends="json-default" namespace="/service">
            // 我这里写的是spring配置的Action
          <action name="uploadImage" class="fileHandleAction" method="uploadImage">  
            <result name="succ" type="json"/> // 返回json数据,即msg属性的信息
        </action>
    </package>
</struts>

四、结语

fileuploader.js 这款插件还是很是强大的,支持进度条的显示,也可以自定义气样式,不过目前我还是没有了解很透这款插件。有时间好好琢磨。希望这篇文章可以对大家有需要的分享下。


最后修改于 2012-11-01

Comments powered by Disqus