Javaweb中的文件批量上传,并将文件路径等信息保存到数据库中

在介绍文件的批量上传之前请先看一看上一篇博文——Javaweb最简单的文件上传

1、. 需求分析:


1.1、 在 upload.jsp 页面上使用 jQuery 实现 "新增一个附件", "删除附件". 但至少需要保留一个.

1.2、 对文件的扩展名和文件的大小进行验证. 以下的规则是可配置的. 而不是写死在程序中的. 

>> 文件的扩展名必须为 .pptx, docx, doc
>> 每个文件的大小不能超过 1 M
>> 总的文件大小不能超过 5 M.

1.3、若验证失败, 则在 upload.jsp 页面上显示错误消息: 

>> 若某一个文件不符合要求: xxx 文件扩展名不合法 或 xxx 文件大小超过 1 M
>> 总的文件大小不能超过 5 M.

1.4、若验证通过, 则进行文件的上传操作

>> 文件上传, 并给一个不能和其他文件重复的名字, 但扩展名不变
>> 在对应的数据表中添加一条记录. 

2、开发前需要导入的jar包

commons-fileupload-1.2.1.jar、commons-io-2.0.jar(依赖包)

c3p0-0.9.2.1.jar、mchange-commons-java-0.2.3.4.jar(依赖包)

mysql-connector-java-5.1.7-bin.jar

(补充:c3p0-config.xml、jquery-1.7.2.js)

3、开发过程

3.1、前台页面(upload.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




Insert title here




	${message }
	
File1:
Desc1:

3.2、servlet设计

package com.xiaojie.fileUpload;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

import com.xiaojie.Del.FileUtils;
import com.xiaojie.beans.FileUploadBean;
import com.xiaojie.db.InsertDbimp;
import com.xiaojie.exception.InvalidExtNameException;
import com.xiaojie.io.Readproperties;

/**
 * Servlet implementation class UploadServlet
 */
@WebServlet("/uploadServlet")
public class UploadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static final String FILE_PATH = "/WEB-INF/files";
	private static final String TEMP="e:\\linshi";

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		String path = null;
		ServletFileUpload upload = getservletFileUpload();
		try {
			//把需要上传的FileItem都放入到该Map中,键:文件的待存放的路径,值:对应的FileItem的对象			
			MapuploadFiles=new HashMap();
			//解析请求,得到FileItem 的集合
			List items = upload.parseRequest(request);
			System.out.println(items);
			//构建FileUploadBean的集合,同时填充uploadFiles
			Listbeans=buildFileUploadBeans(items,uploadFiles);
			//校验扩展名
			vaidateExtName(beans);
			//校验文件的大小:在解析的时候已经校验过了	
			//进行文件的上传操作
			System.out.println(uploadFiles.size());
			upload(uploadFiles);
			//把上传的信息保存到数据库中
			saveBeans(beans);
			path="success.jsp";
			//6. 删除临时文件夹的临时文件
			FileUtils.delAllFile(TEMP);
		} catch (Exception e) {
	
			e.printStackTrace();
			path="upload.jsp";
			request.setAttribute("message", e.getMessage());			
		} 
		request.getRequestDispatcher(path).forward(request, response);
	}

	private void saveBeans(List beans) throws ClassNotFoundException, SQLException, IOException {
		InsertDbimp.save(beans);
	}
	/**
	 * 文件上传前的准备工作. 得到 filePath 和 InputStream
	 * @param uploadFiles
	 * @throws IOException
	 */
	private void upload(Map uploadFiles) throws IOException {
		// TODO Auto-generated method stub
		for(Map.Entry uploadFile:uploadFiles.entrySet()){
			String filePath=uploadFile.getKey();
			FileItem item= uploadFile.getValue();
		
			upload(filePath,item.getInputStream());
			
		}
	
	}
	/**
	 * 文件上传的 IO 方法.
	 * 
	 * @param filePath
	 * @param inputStream
	 * @throws IOException
	 */
	private void upload(String filePath, InputStream inputStream) throws IOException {
		// TODO Auto-generated method stub
		OutputStream out=new FileOutputStream(filePath);
		byte[] buffer=new byte[1024];
		int len=0;
		while((len=inputStream.read(buffer))!=-1){
			out.write(buffer, 0, len);	
		}
		inputStream.close();
		out.close();
		System.out.println(filePath);
	}
	/**
	 * 校验扩展名是否合法
	 * @param beans: 
	 * @throws IOException 
	 */
	private void vaidateExtName(List beans) throws IOException {
		String exts=Readproperties.getInstance().getproperties("exts");
		List extList=Arrays.asList(exts.split(","));
		for(FileUploadBean bean:beans){
			String filename=bean.getFileName();
			String extname=filename.substring(filename.indexOf(".")+1);
			if(!extList.contains(extname)){
				throw new InvalidExtNameException(filename + "文件的扩展名不合法");
			}
		}
		
	}
	/**
	 * 利用传入的 FileItem 的集合, 构建 FileUploadBean 的集合, 同时填充 uploadFiles
	 * 
	 * FileUploadBean 对象封装了: id, fileName, filePath, fileDesc
	 * uploadFiles: Map 类型, 存放文件域类型的  FileItem. 键: 待保存的文件的名字 ,值: FileItem 对象
	 * 
	 * 构建过程:
	 * 1. 对传入 FileItem 的集合进行遍历. 得到 desc 的那个 Map. 键: desc 的 fieldName(desc1, desc2 ...). 
	 * 值: desc 的那个输入的文本值
	 * 
	 * 2. 对传入 FileItem 的集合进行遍历. 得到文件域的那些 FileItem 对象, 构建对应的 key (desc1 ....) 来获取其 desc.
	 * 构建的 FileUploadBean 对象, 并填充 beans 和 uploadFiles
	 * 
	 * @param items
	 * @param uploadFiles
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	private List buildFileUploadBeans(List items, Map uploadFiles) throws UnsupportedEncodingException {
		
		List beans = new ArrayList<>();	
		Map descs = new HashMap<>();
		for(int i = 0; i < items.size(); i++){
			FileItem item = items.get(i);
			if(item.isFormField()){
				descs.put(item.getFieldName(), item.getString("utf-8"));
			}
		}

		for(int i = 0; i < items.size(); i++){
			
			FileItem item = items.get(i);
			FileUploadBean bean = null;
			if(!item.isFormField()){
				String fieldName=item.getFieldName();
				String descName = "desc" + fieldName.substring(fieldName.length() - 1);
				String desc = descs.get(descName); 
				
				//对应文件名
				String fileName = item.getName();
				String filePath = getFilePath(fileName);
				
				bean = new FileUploadBean(fileName, filePath, desc);
				beans.add(bean);
				
				uploadFiles.put(bean.getFilePath(), item);
			}			
		
		}
		return beans;
	}
	/**
	 * 根据跟定的文件名构建一个随机的文件名
	 * 1. 构建的文件的文件名的扩展名和给定的文件的扩展名一致
	 * 2. 利用 ServletContext 的 getRealPath 方法获取的绝对路径
	 * 3. 利用了 Random 和 当前的系统时间构建随机的文件的名字
	 * 
	 * @param fileName
	 * @return
	 */
	private String getFilePath(String fileName) {
		String extName=fileName.substring(fileName.lastIndexOf("."));
		Random random = new Random();		
		String filePath = getServletContext().getRealPath(FILE_PATH) + "\\" + System.currentTimeMillis() + random.nextInt(100000) + extName;
		return filePath;
	}
	/**
	 * 构建 ServletFileUpload 对象
	 * 从配置文件中读取了部分属性, 用户设置约束. 
	 * 该方法代码来源于文档. 
	 * @return
	 */
	private ServletFileUpload getservletFileUpload() throws IOException {
		String fileMaxSize=Readproperties.getInstance().getproperties("file.max.size");
		String totalFileMaxSize=Readproperties.getInstance().getproperties("total.file.max.size");
		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setSizeThreshold(1024*500);//设置内存的临界值为500K
		File temp=new File("TEMP");//当超过500K的时候,存到一个临时文件夹中
		factory.setRepository(temp);
		ServletFileUpload upload = new ServletFileUpload(factory);
		  //解决上传文件名的中文乱码
		upload.setHeaderEncoding("UTF-8"); 
		upload.setSizeMax(Integer.parseInt(totalFileMaxSize));//设置上传的文件总的大小不能超过5M
		upload.setFileSizeMax(Integer.parseInt(fileMaxSize));
		return upload;
	}
	
}

3.3保存到数据库中

这部分的代码基本上是胶水代码,这里就不赘述了。

3.4读取配置文件(补充):

servlet中需要校验文件的合法性的时候,为了便于维护,我们将规定的几种格式的文件类型,规定的上传文件的大小限定等信息放到一个可配置的文件当中,用的时候读取该文件中的键值对即可。
upload.properties配置文件的代码如下:

exts=pptx,docx,doc
file.max.size=1048576
total.file.max.size=5242880

读取upload.properties的类
package com.xiaojie.io;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class Readproperties {
	private static Readproperties rp=null;

	private Readproperties(){
		System.out.println("对象被创建了");
	}
	public static Readproperties getInstance(){
		if(rp==null){
			rp=new Readproperties();
		}
		return rp;
	}
	public String getproperties(String arg0) throws IOException{
		InputStream in = getClass().getClassLoader().getResourceAsStream("upload.properties");  
		// 以上为输入流  
		Properties pt = new Properties();// 创建properties  
		pt.load(in);// 取键值对(加载对应的输入流)
		String xinxi= pt.getProperty(arg0);
		return xinxi;
	}

}

如有疑问请联系本人qq:1913284695

或微信:fyydbc

你可能感兴趣的:(小项目总结)