【前言】
假如您有看过我前面的文章,那么您肯定知道我目前做的项目是需要一部分组件的,譬如:
头像裁剪,图片裁剪,多文件上传,权限管理系统,用户文件管理,bbcode编辑器整合用户文件管理系统等等,
不要急,今天我来说一说多文件上传的解决方案。
【准备】
请先到这个地方下载plupload组件
plupload组件官网
--这个组件很厉害,虽然它默认没有实现java版的后台代码,但没关系。
【背景知识】
【代码编写】
已经知道这些背景以后,那么对plupload的处理应该可以了,
下面一段代码仅供参考,是我用来分析数据及保存数据的例子:
package EWeb.Servlets; import EWeb.Config.AppConfig; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Hashtable; import EWeb.BLL.Member.UserBLL; import EWeb.Config.AppConfig; import EWeb.Model.Member.UserModel; import Easis.Common.HttpUtil; import Easis.Common.JsonHelper; import Easis.Common.StringUtil; import Easis.Common.Validation; import Easis.HTTP.IRequestRunnable; import Easis.HTTP.RequestEX; import Easis.HTTP.RequestFile; import Easis.Media.FileType; import Easis.Media.FileTypeHelper; import Easis.util.OperationResult; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.util.*; /** * Created with IntelliJ IDEA. * User: Administrator * Date: 13-8-4 * Time: 下午3:06 * To change this template use File | Settings | File Templates. */ public class MutiUploader extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); response.setHeader("content-type","text/html;charset=UTF-8"); PrintWriter out=response.getWriter(); //---各个错误代码含义: int errorCode_IOExcption_in_out=100;//无法读写临时文件 int errorCode_IOExcption_in=101;//无法打开input stream输入流 int errorCode_IOExcption_out=102;//无法打开output stream 输出流 int errorCode_IOExcption_move=103;//无法移动临时文件 /************************************ 初始化上次的根本目录或跟目录 ************************************/ RequestEX _req=new RequestEX(request,new IRequestRunnable() { @Override public void run(RequestEX _req1) { } }); String uploadFileName=_req.getParaValueByPost("name"); int _chunkSequence= StringUtil.toInt(_req.getParaValueByPost("chunk")); int _chunkTotal=StringUtil.toInt(_req.getParaValueByPost("chunks")); Hashtable<String,Object> hs_out=new Hashtable<String, Object>(); AppConfig appConfig=new AppConfig(); String realSharePath= HttpUtil.getRealPath(request, appConfig.getServerSharePath()); OperationResult opres=new OperationResult(); System.out.println("父类chunk:"+_req.getParaValueByBoth("chunk")); String _currentPath=_req.getParameterByBoth("CurrentPath").Value; if(Validation.isSafePlainText(_currentPath, new char[]{' ', '/', '_'})==false){ out.print(JsonHelper.getJsonString(getErrorRes(errorCode_IOExcption_in_out, "文件名称包含危险字符,无法继续执行操作。"))); return; } //--检查文件名称 if(StringUtil.isNullOrEmpty(_currentPath)){ _currentPath="/"; } //--保存文件夹 if(_req._FILES==null||_req._FILES.size()<=0){ out.print(JsonHelper.getJsonString(getErrorRes(errorCode_IOExcption_in,"客户端没有传输任何文件数据!"))); return; } RequestFile _requestFile=_req._FILES.get(0); if(_requestFile.FileData==null||_requestFile.FileData.length<=0){ out.print(JsonHelper.getJsonString(getErrorRes(errorCode_IOExcption_in,"请不要传输空文件!"))); return; } System.out.println("当前父类主要参数:name:【"+uploadFileName+"】,chunk:【"+_chunkSequence+"】,chunks:【"+_chunkTotal+"】"); if(_chunkTotal<=0){ out.print(JsonHelper.getJsonString(getErrorRes(errorCode_IOExcption_in,"客户端上传分块数量错误!"))); return; } if(_chunkSequence>=_chunkTotal){ out.print(JsonHelper.getJsonString(getErrorRes(errorCode_IOExcption_in,"客户端当前分块序号不可能大于或等于总分块数!"))); return; } if(StringUtil.isNullOrEmpty(uploadFileName)){ out.print(JsonHelper.getJsonString(getErrorRes(errorCode_IOExcption_in,"请明确当前文件名称!"))); return; } //--检查文件名称 //--保存 String fileName1=_req.getParaValueByPost("name"); fileName1=fileName1.replaceAll("\\.+","\\."); if(Validation.isSafePlainText(fileName1,new char[]{'.',' ','(',')','-'})==false){ out.print(JsonHelper.getJsonString(getErrorRes(errorCode_IOExcption_in,"文件名称包含危险字符!"))); return; } //--判断文件类型 String fileExt=""; if(fileName1.lastIndexOf('.')!=-1){ fileExt=fileName1.substring(fileName1.lastIndexOf('.')+1,fileName1.length()); fileName1=fileName1.substring(0,fileName1.lastIndexOf('.')); } _requestFile.fileType=FileTypeHelper.str2FileType(fileExt); if(_chunkSequence==0){ //--判断开始格式 FileType _fType=FileTypeHelper.getFileType(_requestFile.FileData); if(_fType!=_requestFile.fileType){ out.print(JsonHelper.getJsonString(getErrorRes(errorCode_IOExcption_in,"文件类型与文件后缀名不一致!"))); return; } } //--判断文件类型 if(_requestFile.fileType==FileType.bmp|| _requestFile.fileType==FileType.gif|| _requestFile.fileType== FileType.png|| _requestFile.fileType==FileType.pdf|| _requestFile.fileType==FileType.doc|| _requestFile.fileType==FileType.docx|| _requestFile.fileType==FileType.jpg|| _requestFile.fileType==FileType.zip|| _requestFile.fileType==FileType.flv ||_requestFile.fileType==FileType.gz ||_requestFile.fileType==FileType.wps ||_requestFile.fileType==FileType.wav ||_requestFile.fileType==FileType.wmv ||_requestFile.fileType==FileType.mid ||_requestFile.fileType==FileType.rar ||_requestFile.fileType==FileType.mpg ||_requestFile.fileType==FileType.mp3 ||_requestFile.fileType==FileType.mp4 ){ //--放行 } else{ out.print(JsonHelper.getJsonString(getErrorRes(errorCode_IOExcption_in,"不允许上传该文件类型【"+FileTypeHelper.FileType2Str(_requestFile.fileType)+"】!"))); return; } fileName1+="."+ FileTypeHelper.FileType2Str(_requestFile.fileType); String file_real_path=realSharePath+File.separator+_currentPath+"/"+fileName1; file_real_path=file_real_path.replace('\\','/').replaceAll("/+","/").replace('/',File.separatorChar); //-- //--当前序号的文件名称。 System.out.println("父类相关路径:"+file_real_path); File f_tmp=new File(file_real_path); if(f_tmp.exists()==false){ f_tmp.createNewFile(); } else if(f_tmp.isDirectory()){ f_tmp.createNewFile(); } //--判断是第一次或者是续传 try{ if(_chunkSequence==0){ FileOutputStream fileWriter=new FileOutputStream(f_tmp); fileWriter.write(_req._FILES.get(0).FileData); fileWriter.close(); } else{ //--否则,就追加内容 FileOutputStream fileWriter=new FileOutputStream(f_tmp,true); fileWriter.write(_requestFile.FileData); fileWriter.close(); } out.print(JsonHelper.getJsonString(getSuccessRes())); } catch (Exception e){ out.print(JsonHelper.getJsonString(getErrorRes(errorCode_IOExcption_out,"写入文件时候出错!"+e.getMessage()))); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); } public static Hashtable<String,Object> getErrorRes(int errorCode,String errorMsg){ //die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}'); Hashtable<String,Object> _hs=new Hashtable<String, Object>(); _hs.put("jsonrpc","2.0"); Hashtable<String,Object> _hs_child=new Hashtable<String, Object>(); _hs_child.put("code",errorCode); _hs_child.put("message",errorMsg); _hs.put("error",_hs_child); _hs.put("id","id"); return _hs; } public static Hashtable<String,Object> getSuccessRes(){ //{"jsonrpc" : "2.0", "result" : null, "id" : "id"}'); Hashtable<String,Object> _hs=new Hashtable<String, Object>(); _hs.put("jsonrpc","2.0"); Hashtable<String,Object> _hs_child=new Hashtable<String, Object>(); _hs.put("result","null"); _hs.put("id","id"); return _hs; } }
ok,那么现在来看看一个服务器文件管理器除了上传还需要什么?
【1、】获取文件及文件夹信息;
【2、】添加编辑文件夹。
【3、】图片及附件上传及删除。
ok,为了实现树形导航我用了ztree,这个控件不得不说,好。
然后为了动态获取文件夹信息,用了ajax,动态生成html,这些都不用说了,现在看看效果:
这里是一些截图,但是我认为,
服务器端的面向外网用户的程序不需要这么多权限给他们,除了上传删除下载,其他权限可以限制。