plupload+struts2实现文件上传下载

    plupload是一款优秀的web前端上传框架。使用简单。功能强大。不仅支持文件多上传,进度条。拖拽方式选择文件更重要的是他会自己主动的识别浏览器来选择最合适的上传方式。废话少说先上图:

代码都是測试过的非常好用,仅仅要把jquery路径和版本号改动下面,去plupload官网把jar把下载下来就能够用了。

先看一下uploadUI.jsp源码。uploadUI.jsp就是上图显示的页面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Plupload上传页面</title>
<script type="text/javascript" src="jquery/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="plupload/plupload.full.min.js"></script>
<script type="text/javascript" src="plupload/jquery.ui.plupload/jquery.ui.plupload.js"></script>
<script type="text/javascript" src="js/pop.js"></script>
<style type="text/css">
    html{
     width:100%;
     height:100%;
-webkit-text-size-adjust:none;
-moz-text-size-adjust:none;
-ms-text-size-adjust:none;
-o-text-size-adjust:none;
text-size-adjust:none; 
     }
     /**
     *进度条样式
     */
   #processbar {
    height:20px;
    width: 60%;
    margin-top:15px;
    margin-left:65px;
    background-color:#C7D6E4;
    border: 0px solid #999;
    border-radius:15px;
    }
   .finish {
    height: 20px;
    width:60%;
    background-color:#5CB85C;
    border-radius:15px;
   }
   td{  
     width:200px;  
     height:16px;
     text-align: center;
      }  
</style>
</head>
<body style="font:13px Verdana; background:#eee;color:#333;width:99%">
<br/>
<div id="container" style="margin-left:-9px;width:100%;height:600px;background-color:#EBEBEB;border:1px solid #EBEBEB;">
       <div id="pickfiles" style="background-color:#abcdef;width:100%;height:45px;margin-top:-24px;">
         <span style="font-size:25px;font-family:fantasy;font-weight:bold">文件上传</span>
                 <span style="font-size:15px;font-family:fantasy;text-align:bottom">点击选择文件或拖拽文件至下方空白区</span>
       </div> 
   <div id="drag" style="width:100%;height:300px;background-color:#ffffff;border:1px solid #EBEBEB;overflow-y:auto;">
        <table id="filesTable" style="font-size:14px;margin:0 auto;width:100%;cellpadding=0;cellspacing=0;word-break:break-all; border-collapse: collapse;"> 
           <tr>
              <th>文件名</th><th>文件大小</th><th>进度</th><th>删除</th>
           </tr>
        </table>
   </div>
   <div>
    <button id="uploadfiles">開始上传</button>
    <button id="stopUploadfiles" >停止上传</button>
    <input type="hidden" id="filename" name="filename">
    <input type="hidden" id="filesize" name="filesize">
   </div>
</div>
<br/>
<pre id="console"></pre>
<script type="text/javascript">
var newFlagFlag=true;
window.onload = function () {
var uploader = new plupload.Uploader({
runtimes : 'html5,flash,silverlight,html4',//plupload会在文件上传时依据浏览器的不停选择合适的上传方式
browse_button : 'pickfiles',//选择文件的按钮  
container:'container',//文件上传容器  
url:'file_upload.action',//上传文件路径  
flash_swf_url:'plupload/Moxie.swf',// Flash环境路径设置  
silverlight_xap_url:'plupload/Moxie.xap',//silverlight环境路径设置  
unique_names :true,//生成唯一文件名称  
resize: {   //能够使用该參数对将要上传的图片进行压缩
 width: 100, //指定压缩后图片的宽度。假设没有设置该属性则默觉得原始图片的宽度
 height: 100,//指定压缩后图片的高度,假设没有设置该属性则默觉得原始图片的高度
 crop: true,//是否裁剪图片
 quality: 60,//压缩后图片的质量,仅仅对jpg格式的图片有效,默觉得90
 preserve_headers: false  //压缩后是否保留图片的元数据,true为保留
},
    multipart:true,//为true时将以multipart/form-data的形式来上传文件,为false时则以二进制的格式来上传文件
    multi_selection:true,//能否够在文件浏览对话框中选择多个文件,true为能够,false为不能够。默认true
    file_data_name:'file', //name='file'
    max_retries:5,//当发生plupload.HTTP_ERROR错误时的重试次数,为0时表示不重试
    drop_element:'drag',
filters : [{
title : '全部',  //文件上产过滤器。我这里是全部文件都能够上传
         extensions : '*' 
}],
init: {//当Plupload初始化完毕后触发   监听函数參数:(uploader plupload的实例对象)
PostInit: function() {
document.getElementById('uploadfiles').onclick = function() {//開始上传方法
uploader.start();
return false;
};
document.getElementById('stopUploadfiles').onclick = function() {//停止上传方法
uploader.stop();
return false;
};
},
FilesAdded: function(up, files){//当文件加入到上传队列后触发 
 plupload.each(files, function(file){
$("#filesTable").append("<tr><td class=" + file.id + ">" + file.name + "</td><td>"+plupload.formatSize(file.size)+"</td>"+
"<td id=" +file.id +"><div id='processbar'><div class='finish' id='div_contianer"+file.id+"' style='visibility:hidden;'></div></div></td>"+
   "<td><input type='button' id=" +file.id +" value='删除'></input></td>"+
"</tr>");
});
},
OptionChanged:function(up,option_name,new_value,old_value){//当使用Plupload实例的setOption()方法改变当前配置參数后触发 

},
UploadProgress: function(up, file){  //上传过程中触发  能够用此事件来显示上传进度
//在这写加入进度条
$("#div_contianer"+file.id).css("width",file.percent+"%");
$("#div_contianer"+file.id).text(file.percent+"%");
},
BeforeUpload:function(up, file){  //当队列中的某一个文件正要開始上传前触发 
document.getElementById("div_contianer"+file.id).style.visibility='visible';
},
UploadFile:function(up, file){ //当上传队列中某一个文件開始上传后触发 
$("#filename").val(file.name);
$("#filesize").val(file.size);
},
StateChanged:function(up){ //当上传队列的状态发生改变时触发 

},
QueueChanged:function(up){ //当上传队列发生变化后触发,即上传队列新增了文件或移除了文件。

QueueChanged事件会比FilesAdded或FilesRemoved事件先触发 

},
FilesRemoved:function(up, files){ //当文件从上传队列移除后触发 
             
          return false;
},
ChunkUploaded:function(up,file,responseObject){ //当使用文件小片上传功能时,每个小片上传完毕后触发 

},
UploadComplete:function(up,files){ //当上传队列中全部文件都上传完毕后触发  files为一个数组,里面的元素为本次已完毕上传的全部文件对象
    alert(files[0].name);
},
Error: function(up, err) {
document.getElementById('console').innerHTML += "\nError #" + err.code + ": " + err.message;
}
}
});
uploader.init();
};
</script>
<a href="file_downloadFile.action?filepath=D:\uploadFiles\gaode.txt">点击下载文件</a>
</body>
</html>

在看一下struts.xml文件:

<?xml version="1.0" encoding="UTF-8" ?

>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>


    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <constant name="struts.devMode" value="false" />
    <!-- 错误信息国际化 -->
    <constant name="struts.custom.i18n.resources" value="file"></constant>
    <!-- 上传文件最大限制是100M -->
    <constant name="struts.multipart.maxSize" value="209715200" />
    <constant name="struts.action.extension" value="action" /><!-- struts2的默认路径后缀名是.action -->
    <package name="default" namespace="/" extends="struts-default">
    
         <!-- 文件action -->
         <action name="file_*" class="com.uploadanddownload.action.FileAction" method="{1}">
           <interceptor-ref name="fileUpload">
             <!-- 配置同意上传的文件类型 -->
              <param name="allowedTypes">
                image/jpeg,image/gif,image/png,image/bmp,
                text/css,application/msword,application/octet-stream,text/html,
                application/x-javascript,text/plain,application/zip,application/x-zip-compressed,
                video/x-msvideo,application/msword,
                audio/mpeg,application/pdf,application/vnd.ms-powerpoint,application/excel,
                application/vnd.ms-excel,text/xml,application/xlsx,application/vnd.ms-excel.sheet.macroEnabled.12,
                application/java-archive,
                 application/vnd.ms-excel,application/xlsx,application/vnd.ms-excel.sheet.macroEnabled.12,
                application/java-archive,application/x-cdf,application/x-netcdf,application/x-cpio,application/x-csh,
                application/x-dvi,message/rfc822,text/x-setext,application/x-gtar,application/x-hdf,
                image/ief,application/x-latex,video/mpeg,application/x-troff-man,application/x-troff-me,message/rfc822,
                message/rfc822,application/x-mif,video/quicktime,video/x-sgi-movie,video/mpeg,application/x-troff-ms,
                application/x-netcdf,message/rfc822,application/oda,application/x-pkcs12,application/pkcs7-mime,image/x-portable-bitmap,
                application/x-pkcs12,image/x-portable-graymap,image/x-portable-anymap,application/vnd.ms-powerpoint,
                image/x-portable-pixmap,text/x-python,application/x-python-code,audio/x-pn-realaudio,application/x-pn-realaudio,image/x-cmu-raster,
                image/x-rgb,text/richtext,text/x-sgml,application/x-sh,application/x-shar,application/x-wais-source,application/x-sv4cpio,application/x-sv4crc,
                application/x-shockwave-flash,application/x-troff,application/x-tar,application/x-tcl,application/x-tex,application/x-texinfo,image/tiff,application/x-troff,
                text/tab-separated-values,application/x-ustar,text/x-vcard,audio/x-wav,image/x-xbitmap,application/xml,image/x-xpixmap,image/x-xwindowdump,
                application/kset,application/ksdps,application/kswps,
                application/vnd.openxmlformats-officedocument.wordprocessingml.document,
                application/vnd.openxmlformats-officedocument.presentationml.presentation,
                application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
              </param>
             <!-- 配置同意上传文件的大小(单位字节) 2M-->
           </interceptor-ref>
           
            <!-- 下载配置 -->
            <result type="stream">  <!-- 这个是文件下载的写法 -->
               <param name="contentType">application/octet-stream;charset=ISO8859-1 </param>  
               <param name="inputName">inStream</param>  
               <param name="contentDisposition">attachment;filename="${filename}"</param>  
            </result>  
            <interceptor-ref name="defaultStack"></interceptor-ref><!-- 把struts2的默认拦截器写在result的后边 -->
         </action>
    </package>
</struts>

最后是FileAction中的代码,这个action包括了上传和下载方法,支持不同浏览器下载文件名称乱码等问题:

package com.uploadanddownload.action;


import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import javax.servlet.ServletContext;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import Decoder.BASE64Encoder;
import com.opensymphony.xwork2.ActionSupport;
/**
 * 文件action  
 * @author LEZ
 *2015年5月12日
 */
 public class FileAction extends ActionSupport{
    //序列化id  实现序列化接口时定义的序列化id。反序列化的时候能够依据这个id又一次生成对象
 private static final long serialVersionUID = -8036172233915538118L;
 private File file;   //上传时从页面传过来的文件
 private String fileContentType;    //文件类型  
 private String fileFileName;    //文件名称    
 private String filename;    //下载所用文件名称    
 private ServletContext context;   //上下文环境
 private String mimeType;    //下载的类型转换
 private InputStream inStream;   //输入流  下载必须用
 private String filesize;
 private int fileId;
 private String filepath;//文件路径
 public String getFilepath() {
return filepath;
}
public void setFilepath(String filepath) {
this.filepath =filepath;
}
private String inputCon;//详细输入的条件
public int getFileId() {
return fileId;
}
public void setFileId(int fileId) { 
this.fileId = fileId;
}
public String getFilesize() {
return filesize;
}
public String getInputCon() {
return inputCon;
}
public void setInputCon(String inputCon) {
this.inputCon = inputCon;
}
public void setFilesize(String filesize) {
this.filesize = filesize;
}
 /**
   * 下载方法
   * author:lez
   * 2015年5月19日 下午1:33:21
   */
   public String downloadFile(){  
   return SUCCESS;  
}
   
    public File getFile(){
 return file;
    }
    public String getFileContentType(){
  return fileContentType;
    }
    public String getFileFileName() {
return fileFileName;
}
  //为client提供输入流
    public InputStream getInStream(){
   try {
  File file = new File(filepath);
      inStream = new FileInputStream(file);   
     if (inStream == null) {  
       inStream = new ByteArrayInputStream("Sorry,File not found !".getBytes());  
    }  
   } catch (Exception e) {
   e.printStackTrace();
   }
  return inStream;  
    }
    //依据不同的文件动态给出MIME文件类型
    public String getContentType(){
        //在Tomcat Conf里的web.xml有相应的映射文件
        return ServletActionContext.getServletContext().getMimeType(filename);
    }
    //返回一个文件名称
    public String getFilename() throws IOException{
        String agent=ServletActionContext.getRequest().getHeader("user-agent");//依据http头信息获取相应的浏览器类型
        return encodeDownloadFilename(filename,agent);
    }
    //下载附件名乱码问题 , IE和火狐 解决不同   IE默认是Url编码 火狐默认是base64编码
    public String encodeDownloadFilename(String filename, String agent)
            throws IOException {
        if (agent.contains("Firefox")) { // 火狐浏览器
            filename = "=?UTF-8?B?"
                    + new BASE64Encoder().encode(filename.getBytes("utf-8"))
                    + "?=";
        } else { // IE及其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
       return filename;
    }
    public String getMimeType() {  
 return mimeType;  
 }
public void setFile(File file){
this.file = file;
    }
  public void setFileContentType(String fileContentType){
this.fileContentType = fileContentType;
}  
  public void setFileFileName(String fileFileName) {
 try {
this.fileFileName =fileFileName;
} catch (Exception e) {
e.printStackTrace();
}
}  
public void setFilename(String filename) {
this.filename = filename;
}
  public void setServletContext(ServletContext context) {  
     this.context = context;  
   }  
/**
 * 上传文件方法
 * @return
 */
   public String upload(){
  System.out.println("进入上传");
   try{  
       File file = new File("D:/uploadFiles");    
          if(!file.exists()){    
              file.mkdirs();     
           }  
           //文件拷贝  
           FileUtils.copyFile(this.file,new File(file,this.fileFileName));  
        }catch(Exception e){  
        e.printStackTrace();  
        }  
   return null;
   }
}

posted @ 2016-01-16 16:03  yxwkaifa  阅读(530)  评论(0编辑  收藏  举报