JAVA-使用commos-fileupload实现文件上传与下载
一文件的上传
实体类
在CODE上查看代码片派生到我的代码片 import java.sql.Timestamp; /** * * @Decription 文件上传实体类 * @author 刘楠 * * @time2016-1-31上午11:17:46 */ public class Upfile { private String id;// ID主键 使用uuid随机生成 private String uuidname; // UUID名称 private String filename;//文件名称 private String savepath; // 保存路径 private Timestamp uploadtime; // 上传时间 private String description;// 文件描述 private String username; // 用户名 public Upfile() { super(); } public Upfile(String id, String uuidname, String filename, String savepath, Timestamp uploadtime, String description, String username) { super(); this.id = id; this.uuidname = uuidname; this.filename = filename; this.savepath = savepath; this.uploadtime = uploadtime; this.description = description; this.username = username; } public String getDescription() { return description; } public String getFilename() { return filename; } public String getId() { return id; } public String getSavepath() { return savepath; } public Timestamp getUploadtime() { return uploadtime; } public String getUsername() { return username; } public String getUuidname() { return uuidname; } public void setDescription(String description) { this.description = description; } public void setFilename(String filename) { this.filename = filename; } public void setId(String id) { this.id = id; } public void setSavepath(String savepath) { this.savepath = savepath; } public void setUploadtime(Timestamp uploadtime) { this.uploadtime = uploadtime; } public void setUsername(String username) { this.username = username; } public void setUuidname(String uuidname) { this.uuidname = uuidname; } }
页面
在CODE上查看代码片派生到我的代码片 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'upload.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <h1>文件上传</h1> <form action="${pageContext.request.contextPath }/upload" method="post" enctype="multipart/form-data"> <table> <tr> <td> 上传用户名:</td> <td><input type="text" name="username"/></td> </tr> <tr> <td> 上传文件:</td> <td><input type="file" name="file"/></td> </tr> <tr> <td> 描述:</td> <td><textarea rows="5" cols="50" name="description"></textarea></td> </tr> <tr> <td><input type="submit" value="上传开始"/></td> </tr> </table> </form> <div>${msg }</div> <a href="${pageContext.request.contextPath }/index.jsp">返回主页</a> </body> </html>
Servlet
在CODE上查看代码片派生到我的代码片 import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException; import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException; import org.apache.commons.fileupload.servlet.ServletFileUpload; import com.itheima.domain.Upfile; import com.itheima.exception.MyException; import com.itheima.service.UpfileService; import com.itheima.service.impl.UpfileServiceImpl; import com.itheima.untils.WebUntil; public class UploadFileServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //判断表单是不是多个部分组成的 if(!ServletFileUpload.isMultipartContent(request)){ request.setAttribute("msg", "表单个设置错误,请检查enctype属性是是否设置正确"); request.getRequestDispatcher("/upload.jsp").forward(request, response); return ; } //是多部分组成的就获取并遍历返回一个文件上传对象,包含上传的所有信息 try { Upfile upfile=WebUntil.upload(request); UpfileService upfileService=new UpfileServiceImpl(); boolean flag=upfileService.add(upfile); if(flag){ request.setAttribute("msg", "上传成功"); request.getRequestDispatcher("/upload.jsp").forward(request, response); return ; }else{ request.setAttribute("msg", "上传失败,请重试"); request.getRequestDispatcher("/upload.jsp").forward(request, response); return ; } }catch (FileSizeLimitExceededException e) { e.printStackTrace(); request.setAttribute("msg", "单个文件大小 ,超过最大限制"); request.getRequestDispatcher("/upload.jsp").forward(request, response); return ; } catch (SizeLimitExceededException e) { e.printStackTrace(); request.setAttribute("msg", "总文件大小 ,超过最大限制"); request.getRequestDispatcher("/upload.jsp").forward(request, response); return ; } } }
工具类
在CODE上查看代码片派生到我的代码片 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.util.ArrayList; import java.util.List; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException; import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.ProgressListener; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import com.itheima.domain.Upfile; import com.itheima.exception.MyException; /** * 文件上传工具类 * @Decription TODO * @author 刘楠 * * @time2016-1-31下午12:56:02 */ public class WebUntil { /** * 文件上传的方法 * @param request 请求参数传入 * @return 返回一个Upfile对象 * @throws FileSizeLimitExceededException * @throws SizeLimitExceededException * @throws IOException */ public static Upfile upload(HttpServletRequest request) throws FileSizeLimitExceededException, SizeLimitExceededException { Upfile upfile=new Upfile(); ArrayList<String> fileList=initList(); try { //获取磁盘文件对象工厂 DiskFileItemFactory factory=new DiskFileItemFactory(); String tmp=request.getSession().getServletContext().getRealPath("/tmp"); System.out.println(tmp); //初始化工厂 setFactory(factory,tmp); //获取文件上传解析器 ServletFileUpload upload=new ServletFileUpload(factory); //初始化解析器 setUpload(upload); //获取文件列表集合 List<FileItem> list = upload.parseRequest(request); //遍历 for (FileItem items : list) { //判断 是不是普通表单个对象 if(items.isFormField()){ //获取上传表单的name String fieldName=items.getFieldName(); //value String fieldValue=items.getString("UTF-8"); //判断 if("username".equals(fieldName)){ //设置 upfile.setUsername(fieldValue); }else if("description".equals(fieldName)){ //设置属性 upfile.setDescription(fieldValue); } }else{ //是文件就准备上传 //获取文件名 String filename=items.getName(); //处理因为浏览器不同而导致的 获得 的 文件名的 差异 int index=filename.lastIndexOf("\\"); if(index!=-1){ filename=filename.substring(index+1); } //生成随机的文件名 String uuidname=generateFilename(filename); //获取上传的文件路径 String savepath=request.getSession().getServletContext().getRealPath("/WEB-INF/upload"); //获取请求对象中的输入流 InputStream in = items.getInputStream(); //将文件打散存放在不同的路径,求出路径 savepath=generateRandomDir(savepath,uuidname); //复制文件 uploadFile(in,savepath,uuidname); String id=UUID.randomUUID().toString(); upfile.setId(id); upfile.setSavepath(savepath); upfile.setUuidname(uuidname); upfile.setFilename(filename); //清除缓存 items.delete(); } } }catch ( FileUploadBase.FileSizeLimitExceededException e) { //抛出出异常 throw e; } catch (FileUploadBase.SizeLimitExceededException e) { //抛出出异常 throw e; }catch (FileUploadException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return upfile; } /** * 初始化文件列表 * @return */ private static ArrayList<String> initList() { ArrayList<String> list=new ArrayList<String>(); list.add(".jpg"); list.add(".rar"); list.add(".txt"); list.add(".png"); return list; } /** * 复制文件 * @param in items中的输入流 * @param savepath 保存路径 * @param uuidname 文件名 */ private static void uploadFile(InputStream in, String savepath, String uuidname) { //获取文件 File file=new File(savepath, uuidname); OutputStream out = null; try { int len=0; byte [] buf=new byte[1024]; //获取输出流 out = new FileOutputStream(file); while((len=in.read(buf))!=-1){ out.write(buf, 0, len); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ try { in.close(); } catch (IOException e) { e.printStackTrace(); } try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 生成随机的存放路径 * @param savepath 保存路径 * @param uuidname 生成的uuid名称 * @return * 使用hashcode完成 */ private static String generateRandomDir(String savepath, String uuidname) { //转化为hashcode System.out.println("上传路径"+savepath); System.out.println("UUIDNAME"+uuidname); int hashcode=uuidname.hashCode(); //容器 StringBuilder sb=new StringBuilder(); while(hashcode>0){ //与上15 int tmp=hashcode&0xf; sb.append("/"); sb.append(tmp+""); hashcode=hashcode>>4; } //拼接新的路径 String path=savepath+sb.toString(); System.out.println("path"+path); File file=new File(path); //判断路径存不存在 if(!file.exists()){ //不存在就创建 file.mkdirs(); } //返回保存路径 return path; } /** * 生成新的文件名 * @param uuidname 随机的ID名字 * @param filename 原来的名 * @return */ private static String generateFilename( String filename) { String uuidname=UUID.randomUUID().toString(); return uuidname.replace("-", "").toString()+"_"+filename; } /** * 初始化解析器 * @param upload */ private static void setUpload(ServletFileUpload upload) { // 设置 字符编码 upload.setHeaderEncoding("utf-8"); //设置文件大小 upload.setFileSizeMax(1024*1024*20); //设置总文件大小 upload.setSizeMax(1024*1024*50); //设置进度监听器 upload.setProgressListener(new ProgressListener() { public void update(long pBytesRead, long pContentLength, int pItems) { System.out.println("已经读取: "+pBytesRead+",总共有: "+pContentLength+", 第"+pItems+"个"); } }); } /** * 工厂初始化方法 * @param factory * @param tmp 缓冲目录 */ private static void setFactory(DiskFileItemFactory factory, String tmp) { /// 配置初始化值缓冲区 factory.setSizeThreshold(1024*1024); File file=new File(tmp); //设置缓冲目录 factory.setRepository(file); } }
二文件下载
Servlet
public class DownupfileServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取ID String id=request.getParameter("id"); //业务层的接口 UpfileService upfileService=new UpfileServiceImpl(); //根据ID查找这个对象 Upfile upfile=upfileService.findUpfileById(id); if(upfile==null){ return; } //获取文件的真实名称 String filename=upfile.getFilename(); //如果文件名中有中文,需要转码,不然就下载时没有文件名 filename=URLEncoder.encode(filename, "utf-8"); //更改过的名称 String uuidname=upfile.getUuidname(); //保存路径 String savepath=upfile.getSavepath(); File file=new File(savepath,uuidname); //判断文件 是否存在 if(!file.exists()){ request.setAttribute("msg", "下载 的文件过期了"); request.getRequestDispatcher("/index").forward(request, response); return; } //设置文件下载响应头信息 response.setHeader("Content-disposition", "attachement;filename="+filename); //使用IO流输出 InputStream in = new FileInputStream(file); ServletOutputStream out = response.getOutputStream(); int len=0; byte [] buf=new byte[1024]; while((len=in.read(buf))!=-1){ out.write(buf, 0, len); } in.close(); } }
数据库
create database upload_download_exercise; use upload_download_exercise; create table upfiles( id varchar(100), //使用UUID生成 uuidname varchar(255),//uuid加上原来的文件名 filename varchar(100),//真实文件名 savepath varchar(255),//保存路径 uploadtime timestamp,//上传时间 description varchar(255),//描述 username varchar(10) 上传人 );