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

来源:互联网 发布:彩虹岛 知乎 编辑:程序博客网 时间:2024/05/01 04:31

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">在介绍文件的批量上传之前请先看一看上一篇博文——Javaweb最简单的文件上传</span>

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"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title><script type="text/javascript" src="jquery-1.7.2.js"></script><script type="text/javascript">$(function(){var i=2;$("#addFile").click(function(){$(this).parent().parent().before("<tr class='file'><td>File"+i+":</td><td><input type='file' name='file"+i+"'/></td></tr>"+"<tr class='desc'><td>Desc"+i+":</td><td><input type='text' name='desc"+i+"'/><button id='delete"+i+"'>删除</button></td></tr>");i++;//获取新添加的删除按钮$("#delete"+(i-1)).click(function(){var $tr=$(this).parent().parent();$tr.prev("tr").remove(); $tr.remove();  //对i重写排序 $(".file").each(function(index){ var n=index+1; $(this).find("td:first").text("File"+n); $(this).find("td:last input").attr("name","file"+n);  }); $(".desc").each(function(index){ var n=index+1; $(this).find("td:first").text("Desc"+n); $(this).find("td:last input").attr("name","desc"+n);  });});return false;});})</script></head><body><font color="red">${message }</font><br><form action="uploadServlet" method="post" enctype="multipart/form-data"><table><tr class="file"><td>File1:</td><td><input type="file" name="file1"/></td></tr><tr class="desc"><td>Desc1:</td><td><input type="text" name="desc1"/></td></tr><tr><td><button id="addFile">新增一个附件</button></td><td><input type="submit" value="提交"/></td></tr></table></form></body></html>

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的对象Map<String, FileItem>uploadFiles=new HashMap<String, FileItem>();//解析请求,得到FileItem 的集合List<FileItem> items = upload.parseRequest(request);System.out.println(items);//构建FileUploadBean的集合,同时填充uploadFilesList<FileUploadBean>beans=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<FileUploadBean> beans) throws ClassNotFoundException, SQLException, IOException {InsertDbimp.save(beans);}/** * 文件上传前的准备工作. 得到 filePath 和 InputStream * @param uploadFiles * @throws IOException */private void upload(Map<String, FileItem> uploadFiles) throws IOException {// TODO Auto-generated method stubfor(Map.Entry<String, FileItem> 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 stubOutputStream 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<FileUploadBean> beans) throws IOException {String exts=Readproperties.getInstance().getproperties("exts");List<String> 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<String, FileItem> 类型, 存放文件域类型的  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<FileUploadBean> buildFileUploadBeans(List<FileItem> items, Map<String, FileItem> uploadFiles) throws UnsupportedEncodingException {List<FileUploadBean> beans = new ArrayList<>();Map<String, String> 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);//设置内存的临界值为500KFile temp=new File("TEMP");//当超过500K的时候,存到一个临时文件夹中factory.setRepository(temp);ServletFileUpload upload = new ServletFileUpload(factory);  //解决上传文件名的中文乱码upload.setHeaderEncoding("UTF-8"); upload.setSizeMax(Integer.parseInt(totalFileMaxSize));//设置上传的文件总的大小不能超过5Mupload.setFileSizeMax(Integer.parseInt(fileMaxSize));return upload;}}

3.3保存到数据库中

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

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

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

exts=pptx,docx,docfile.max.size=1048576total.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;}}

3.4 整个项目的目录结构


最后运行upload.jsp即可看到效果,如果您还有什么不懂的地方请点击下面的链接,可以直接下载我的整个项目工程文件:
https://yunpan.cn/cPzGeAr2eGMYw  访问密码 3b9a
3 0
原创粉丝点击