多文件上传你学废了吗?

   日期:2020-10-17     浏览:91    评论:0    
核心提示:这里写目录标题一级目录二级目录三级目录一级目录二级目录三级目录

自己封装文件上传

  • 需要的jar包
  • 文件上传的几大要素
  • 构建文件上传构造方法
  • 文件上传的执行流程
  • 前端页面文件提交
  • 服务端的处理

需要的jar包

commons-fileupload-1.3.1.jar
commons-io-2.2.jar

导入了这两个包就可以用java进行文件上传了

文件上传的几大要素

  1. 上传的目标路径(就是要上传到服务器的那个目录)
  2. 需要有文件名 (有时需要生成随机id标识)
  3. 文件大小限制
  4. 文件类型限制
  5. 文件上传过程中的临时文件夹
  6. 文件上传过程中的内存缓存大小

我们可以将以上的几个属性封装成为类属性

	private static final String DEFAULT_TEMP_FILEPATH = "D:\\temp\\buffer\\";//默认临时路径

    private static final String[] DEFAULT_FILETYPE = { "jpg", "png", "bmp", "gif"};//默认上传的文件类型

    private static final int DEFAULT_SIZE_THRESHOLD = 1024 * 4;//默认缓存大小4k

    private static final int DEFAULT_SIZE_MAX = 1024 * 5000;//默认最大文件大小5mb

    private String fileLoadPath; //上传目标的路径

    private String fileName; //文件名

    private String tempFilePath; //临时文件夹

    private String[] fileType; //允许的文件类型

    private int sizeThreshold; //上传缓存区大小

    private int sizeMax; //上传文件最大大小限制

    private DiskFileItemFactory factory; //磁盘文件工厂

    private ServletFileUpload upload; //文件上传对象

前属性为默认值。

构建文件上传构造方法

我们进行文件上传是肯定要使用上面这个对象进行操作,那么我们得在这个对象实例化的时候做一些事情,比如初始化一些重要参数:

第一个构造方法:


    public FileLoadUtil(String loadPath, String tempFilePath, String[] fileType, int sizeThreshold, int sizeMax) { 
        this.fileLoadPath = loadPath; //上传的目标路径
        this.tempFilePath = tempFilePath; //临时文件夹
        this.fileType = fileType; //指定文件类型
        this.sizeThreshold = sizeThreshold;  //缓存大小
        this.sizeMax = sizeMax; //文件最大允许大小
    }

第二个构造方法:


    public FileLoadUtil(String loadPath) { 
        this.tempFilePath = DEFAULT_TEMP_FILEPATH; //设置默认的临时路径
        this.fileType = DEFAULT_FILETYPE; //设置默认运行的文件类型
        this.sizeThreshold = DEFAULT_SIZE_THRESHOLD; //设置默认的缓存大小
        this.sizeMax = DEFAULT_SIZE_MAX; //设置默认的最大文件允许大小
        this.fileLoadPath = loadPath; //设值文件上传目标路径
        this.factory = new DiskFileItemFactory(); //实例化磁盘文件工厂对象
    }

第三个:


    public FileLoadUtil(){ 

    }

接下来就是一些get 和 set的方法的定义了,这里不会列出,后面会一起把完整的代码列出来。

文件上传的执行流程

我将此执行流程分为一个个的方法,每个方法都作为一个模块,这样可以方便以后扩展和维护。

  1. 先创建临时文件夹

public boolean createTempDirectory() { 
    File tempPatchFile = new File("D:\\temp\\buffer\\");
    //检查目录是否存在
    if (!tempPatchFile.exists()) { 
        //创建该目录
        if (!tempPatchFile.mkdirs()) { 
            return false;
        }
    }
    return true;
}
  1. 设置文件上传参数

public void setUploadParam() { 
    //设置缓存大小
    factory.setSizeThreshold(sizeThreshold);
    //设置临时文件夹
    factory.setRepository(new File(tempFilePath));
    //实例化文件上传对象
    upload = new ServletFileUpload(factory);
    //设置上传文件最大大小
    upload.setSizeMax(sizeMax);
}
  1. 处理请求的文件集合

public List<String> processFormFile(List<FileItem> fileItems) throws Exception { 
	//存放文件名的集合
    List<String> nameArr = new ArrayList<>();
    //用于迭代遍历fileItems
    Iterator<FileItem> itemIterator = fileItems.iterator();
    //遍历fileItems集合
    while (itemIterator.hasNext()) { 
        //获取List<FileItem>集合中的每一个FileItem项
        FileItem fileItem = itemIterator.next();
        //判断该表单是否为file类型(file:false,nofile:true)
        if (!fileItem.isFormField()) { 
            String name;
            //此处上传单个文件
            if((name = fileUploading(fileItem)) != null)
            	//将文件名保存至集合
                nameArr.add(name);
        }
    }
    return nameArr;
}
  1. 文件上传主要实现

    private String fileUploading(FileItem fileItem) throws Exception { 
        String fileName = fileItem.getName();
        //将文件类型数组转换为ArrayList集合
        List<String> fileType = Arrays.asList(this.fileType);
        //获取文件后缀名
        String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
        //如果不匹配返回true
        if (!fileType.contains(ext)) { 
            System.out.println("文件类型不符合");
        } else { 
            //文件名不能为空和空字符
            if (fileName != null && !fileName.equals("")) { 
                //目标文件对象
                File fullFile = new File(fileName);
                //上传路径对象
                File fileSave = new File(fileLoadPath, fullFile.getName());
                //将文件上传
                fileItem.write(fileSave);
                //返回文件名
                return fileName;
            }
        }
        return null;
    }

以上4个方法就可以实现多文件上传了,接下来只剩下一个主调方法来将以上的流程组合起来:


public List<String> defUpload(HttpServletRequest req) throws Exception{ 
	//先创临时文件夹
    if(!this.createTempDirectory()){ 
        System.out.println("创建文件夹失败");
    }
    //设置文件上传参数
    this.setUploadParam();
    List<FileItem> fileItems = null;
    //判断是否为文件上传表单
    if(ServletFileUpload.isMultipartContent(req)) { 
    	//从请求中获取文件集合
        fileItems = upload.parseRequest(req);
        //返回文件上传后的文件名称集合
        return this.processFormFile(fileItems);
    }
    return null;
}

至此这个类已经写好了。

前端页面文件提交

我们通常有两种方式提交文件,一个是通过form表单提交,一个是通过ajax异步提交,那么在这个案例中,我将通过使用ajax来提交文件。

<input type = "file"/>
<input type = "file"/>
<input type = "file"/>
<button id = "cli">上传</button>

上面我定义了几个input标签,类型文文件类型,其中没有用到form表单。当我点击上传按钮的时候就会将这三个标签中的文件上传至服务器。
以下是我的js代码,利用了jquery的ajax:

$("#cli").click(function(){ 
	var form = new FormData();
	var fileobjs = new Array();
	for(var i = 0; i < $("input[type='file']").length; i++) { 
		var ele = document.getElementsByTagName("input");
		fileobjs[i] = ele[i].files[0]
	}
	
	for(var i = 0; i < fileobjs.length; i++) { 
		form.append("img", fileobjs[i]);
	}
	fileUpload(form)
})

上面是获取input中的文件并封装到FormData的一个过程,然后再将form中的数据交给fileUpload提交到服务器上传。
现在看看fileUpload方法:

function fileUpload(form) { 
    $.ajax({ 
        type:"post",
        async:false,
        url:"/MyFileUpload/file",
        data:form,
        dataType:"text",
        processData : false, // 使数据不做处理
        contentType : false, // 不要设置Content-Type请求头
        success:function (data) { 
        },
        error:function(){ 
            alert("FBI Waring")
        }
    })
}

我们在这里要加上这两个属性设置 processData : false, contentType : false,这样请求到服务器是就不会是个对象了,保证了数据的可上传性。

服务端的处理

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
	//文件上传的工具类
	FileLoadUtil fileLoadUtil = new FileLoadUtil("D:/img");
	try { 
		//获取到成功上传的文件集合
		List<String> list = fileLoadUtil.defUpload(req);

		if (list != null) { 
			for (String string : list) { 
				System.out.println(string + "已成功上传...");
			}
			System.out.println(list.size()+"个文件已成功上传");
		} else { 
			System.out.println("上传失败");
		}
	} catch (Exception e) { 
		e.printStackTrace();
	}
}

最后我把封装好的工具类奉上,如果是初学可以参考一下,尝试自己改变其中的定义,让他变得更好:

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;


public class FileLoadUtil { 

    private static final String DEFAULT_TEMP_FILEPATH = "D:\\temp\\buffer\\";//默认临时路径

    private static final String[] DEFAULT_FILETYPE = { "jpg", "png", "bmp", "gif"};//默认上传的文件类型

    private static final int DEFAULT_SIZE_THRESHOLD = 1024 * 4;//默认缓存大小4k

    private static final int DEFAULT_SIZE_MAX = 1024 * 5000;//默认最大文件大小5mb

    private String fileLoadPath; //上传目标的路径

    private String fileName; //文件名

    private String tempFilePath; //临时文件夹

    private String[] fileType; //允许的文件类型

    private int sizeThreshold; //上传缓存区大小

    private int sizeMax; //上传文件最大大小限制

    private DiskFileItemFactory factory; //磁盘文件工厂

    private ServletFileUpload upload; //文件上传对象

    
    public FileLoadUtil(String loadPath, String tempFilePath, String[] fileType, int sizeThreshold, int sizeMax) { 
        this.fileLoadPath = loadPath;
        this.tempFilePath = tempFilePath;
        this.fileType = fileType;
        this.sizeThreshold = sizeThreshold;
        this.sizeMax = sizeMax;
    }

    
    public FileLoadUtil(String loadPath) { 
        this.tempFilePath = DEFAULT_TEMP_FILEPATH;
        this.fileType = DEFAULT_FILETYPE;
        this.sizeThreshold = DEFAULT_SIZE_THRESHOLD;
        this.sizeMax = DEFAULT_SIZE_MAX;
        this.fileLoadPath = loadPath;
        this.factory = new DiskFileItemFactory();
    }

    
    public FileLoadUtil(){ 

    }

    
    public static String getDefaultTempFilepath() { 
        return DEFAULT_TEMP_FILEPATH;
    }

    
    public String getFileLoadPath() { 
        return fileLoadPath;
    }

    public void setFileLoadPath(String fileLoadPath) { 
        this.fileLoadPath = fileLoadPath;
    }

    public String getFileName() { 
        return fileName;
    }

    public void setFileName(String fileName) { 
        this.fileName = fileName;
    }

    public String getTempFilePath() { 
        return tempFilePath;
    }

    public void setTempFilePath(String tempFilePath) { 
        this.tempFilePath = tempFilePath;
    }

    public String[] getFileType() { 
        return fileType;
    }

    public void setFileType(String[] fileType) { 
        this.fileType = fileType;
    }

    public int getSizeThreshold() { 
        return sizeThreshold;
    }

    public void setSizeThreshold(int sizeThreshold) { 
        this.sizeThreshold = sizeThreshold;
    }

    public int getSizeMax() { 
        return sizeMax;
    }

    public void setSizeMax(int sizeMax) { 
        this.sizeMax = sizeMax;
    }

    
    public boolean createTempDirectory() { 
        File tempPatchFile = new File("D:\\temp\\buffer\\");
        //检查目录是否存在
        if (!tempPatchFile.exists()) { 
            //创建该目录
            if (!tempPatchFile.mkdirs()) { 
                return false;
            }
        }
        return true;
    }

    
    public void setUploadParam() { 
        //设置缓存大小
        factory.setSizeThreshold(sizeThreshold);
        //设置临时文件夹
        factory.setRepository(new File(tempFilePath));
        //实例化文件上传对象
        upload = new ServletFileUpload(factory);
        //设置上传文件最大大小
        upload.setSizeMax(sizeMax);
    }

    
    public List<String> processFormFile(List<FileItem> fileItems) throws Exception { 
    	//存放文件名的集合
        List<String> nameArr = new ArrayList<>();
        //用于迭代遍历fileItems
        Iterator<FileItem> itemIterator = fileItems.iterator();
        //遍历fileItems集合
        while (itemIterator.hasNext()) { 
            //获取List<FileItem>集合中的每一个FileItem项
            FileItem fileItem = itemIterator.next();
            //判断该表单是否为file类型(file:false,nofile:true)
            if (!fileItem.isFormField()) { 
                String name;
                //此处上传单个文件
                if((name = fileUploading(fileItem)) != null)
                	//将文件名保存至集合
                    nameArr.add(name);
            }
        }
        return nameArr;
    }

    
    private String fileUploading(FileItem fileItem) throws Exception { 
        String fileName = fileItem.getName();
        //将文件类型数组转换为ArrayList集合
        List<String> fileType = Arrays.asList(this.fileType);
        //获取文件后缀名
        String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
        //如果不匹配返回true
        if (!fileType.contains(ext)) { 
            System.out.println("文件类型不符合");
        } else { 
            //文件名不能为空和空字符
            if (fileName != null && !fileName.equals("")) { 
                //目标文件对象
                File fullFile = new File(fileName);
                //上传路径对象
                File fileSave = new File(fileLoadPath, fullFile.getName());
                //将文件上传
                fileItem.write(fileSave);
                //返回文件名
                return fileName;
            }
        }
        return null;
    }


    
    public List<String> defUpload(HttpServletRequest req) throws Exception{ 
    	//先创临时文件夹
        if(!this.createTempDirectory()){ 
            System.out.println("创建文件夹失败");
        }
        //设置文件上传参数
        this.setUploadParam();
        List<FileItem> fileItems = null;
        //判断是否为文件上传表单
        if(ServletFileUpload.isMultipartContent(req)) { 
        	//从请求中获取文件集合
            fileItems = upload.parseRequest(req);
            //返回文件上传后的文件名称集合
            return this.processFormFile(fileItems);
        }
        return null;
    }
}

其端页面很灵活,可以自己动手制作

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服