【前言】
假如您有看过我前面的文章,那么您肯定知道我目前做的项目是需要一部分组件的,譬如:
头像裁剪,图片裁剪,多文件上传,权限管理系统,用户文件管理,bbcode编辑器整合用户文件管理系统等等,
不要急,今天我来说一说多文件上传的解决方案。
【准备】
请先到这个地方下载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,这些都不用说了,现在看看效果:
这里是一些截图,但是我认为,
服务器端的面向外网用户的程序不需要这么多权限给他们,除了上传删除下载,其他权限可以限制。