只为成功找方法_第1页
只为成功找方法_第2页
只为成功找方法_第3页
只为成功找方法_第4页
只为成功找方法_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

只为成功找方法,不为失败找借口!JavaWeb学习总结(五十)文件上传和下载在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现。对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择采用apache的开源工具common-fileupload这个文件上传组件。这个common-fileupload上传组件的jar包可以去apache官网上面下载,也可以在struts的lib文件夹下面找到,struts上传的功能就是基于这个实现的。common-fileupload是依赖于common-io这个包的,所以还需要下载这个包。一、开发环境搭建创建一个FileUploadAndDownLoad项目,加入Apache的commons-fileupload文件上传组件的相关Jar包,如下图所示:二、实现文件上传2.1、文件上传页面和消息提示页面upload.jsp页面的代码如下: 1 2 3 4 5 文件上传 6 7 8 9 10 上传用户:11 上传文件1:12 上传文件2:13 14 15 16 message.jsp的代码如下: 1 2 3 4 5 消息提示 6 7 8 9 $message10 11 2.2、处理文件上传的ServletUploadHandleServlet的代码如下: 1 package me.gacl.web.controller; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.util.List; 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 import mons.fileupload.FileItem; 13 import mons.fileupload.disk.DiskFileItemFactory; 14 import mons.fileupload.servlet.ServletFileUpload; 15 16 public class UploadHandleServlet extends HttpServlet 17 18 public void doGet(HttpServletRequest request, HttpServletResponse response) 19 throws ServletException, IOException 20 /得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全 21 String savePath = this.getServletContext().getRealPath(/WEB-INF/upload); 22 File file = new File(savePath); 23 /判断上传文件的保存目录是否存在 24 if (!file.exists() & !file.isDirectory() 25 System.out.println(savePath+目录不存在,需要创建); 26 /创建目录 27 file.mkdir(); 28 29 /消息提示 30 String message = ; 31 try 32 /使用Apache文件上传组件处理文件上传步骤: 33 /1、创建一个DiskFileItemFactory工厂 34 DiskFileItemFactory factory = new DiskFileItemFactory(); 35 /2、创建一个文件上传解析器 36 ServletFileUpload upload = new ServletFileUpload(factory); 37 /解决上传文件名的中文乱码 38 upload.setHeaderEncoding(UTF-8); 39 /3、判断提交上来的数据是否是上传表单的数据 40 if(!ServletFileUpload.isMultipartContent(request) 41 /按照传统方式获取数据 42 return; 43 44 /4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List集合,每一个FileItem对应一个Form表单的输入项 45 List list = upload.parseRequest(request); 46 for(FileItem item : list) 47 /如果fileitem中封装的是普通输入项的数据 48 if(item.isFormField() 49 String name = item.getFieldName(); 50 /解决普通输入项的数据的中文乱码问题 51 String value = item.getString(UTF-8); 52 /value = new String(value.getBytes(iso8859-1),UTF-8); 53 System.out.println(name + = + value); 54 else/如果fileitem中封装的是上传文件 55 /得到上传的文件名称, 56 String filename = item.getName(); 57 System.out.println(filename); 58 if(filename=null | filename.trim().equals() 59 continue; 60 61 /注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如: c:ab1.txt,而有些只是单纯的文件名,如:1.txt 62 /处理获取到的上传文件的文件名的路径部分,只保留文件名部分 63 filename = filename.substring(filename.lastIndexOf()+1); 64 /获取item中的上传文件的输入流 65 InputStream in = item.getInputStream(); 66 /创建一个文件输出流 67 FileOutputStream out = new FileOutputStream(savePath + + filename); 68 /创建一个缓冲区 69 byte buffer = new byte1024; 70 /判断输入流中的数据是否已经读完的标识 71 int len = 0; 72 /循环将输入流读入到缓冲区当中,(len=in.read(buffer)0就表示in里面还有数据 73 while(len=in.read(buffer)0) 74 /使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + + filename)当中 75 out.write(buffer, 0, len); 76 77 /关闭输入流 78 in.close(); 79 /关闭输出流 80 out.close(); 81 /删除处理文件上传时生成的临时文件 82 item.delete(); 83 message = 文件上传成功!; 84 85 86 catch (Exception e) 87 message= 文件上传失败!; 88 e.printStackTrace(); 89 90 91 request.setAttribute(message,message); 92 request.getRequestDispatcher(/message.jsp).forward(request, response); 93 94 95 public void doPost(HttpServletRequest request, HttpServletResponse response) 96 throws ServletException, IOException 97 98 doGet(request, response); 99 100 在Web.xml文件中注册UploadHandleServlet1 2 UploadHandleServlet3 me.gacl.web.controller.UploadHandleServlet4 5 6 7 UploadHandleServlet8 /servlet/UploadHandleServlet9 运行效果如下:文件上传成功之后,上传的文件保存在了WEB-INF目录下的upload目录,如下图所示:2.3、文件上传的细节上述的代码虽然可以成功将文件上传到服务器上面的指定目录当中,但是文件上传功能有许多需要注意的小细节问题,以下列出的几点需要特别注意的1、为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。2、为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名。3、为防止一个目录下面出现太多文件,要使用hash算法打散存储。4、要限制上传文件的最大值。5、要限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。针对上述提出的5点细节问题,我们来改进一下UploadHandleServlet,改进后的代码如下: 1 package me.gacl.web.controller; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.util.List; 8 import java.util.UUID; 9 10 import javax.servlet.ServletException; 11 import javax.servlet.http.HttpServlet; 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 import mons.fileupload.FileItem; 15 import mons.fileupload.FileUploadBase; 16 import mons.fileupload.ProgressListener; 17 import mons.fileupload.disk.DiskFileItemFactory; 18 import mons.fileupload.servlet.ServletFileUpload; 19 20 /* 21 * ClassName: UploadHandleServlet 22 * Description: TODO(这里用一句话描述这个类的作用) 23 * author: 孤傲苍狼 24 * date: 2015-1-3 下午11:35:50 25 * 26 */ 27 public class UploadHandleServlet extends HttpServlet 28 29 public void doGet(HttpServletRequest request, HttpServletResponse response) 30 throws ServletException, IOException 31 /得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全 32 String savePath = this.getServletContext().getRealPath(/WEB-INF/upload); 33 /上传时生成的临时文件保存目录 34 String tempPath = this.getServletContext().getRealPath(/WEB-INF/temp); 35 File tmpFile = new File(tempPath); 36 if (!tmpFile.exists() 37 /创建临时目录 38 tmpFile.mkdir(); 39 40 41 /消息提示 42 String message = ; 43 try 44 /使用Apache文件上传组件处理文件上传步骤: 45 /1、创建一个DiskFileItemFactory工厂 46 DiskFileItemFactory factory = new DiskFileItemFactory(); 47 /设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。 48 factory.setSizeThreshold(1024*100);/设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB 49 /设置上传时生成的临时文件的保存目录 50 factory.setRepository(tmpFile); 51 /2、创建一个文件上传解析器 52 ServletFileUpload upload = new ServletFileUpload(factory); 53 /监听文件上传进度 54 upload.setProgressListener(new ProgressListener() 55 public void update(long pBytesRead, long pContentLength, int arg2) 56 System.out.println(文件大小为: + pContentLength + ,当前已处理: + pBytesRead); 57 /* 58 * 文件大小为:14608,当前已处理:4096 59 文件大小为:14608,当前已处理:7367 60 文件大小为:14608,当前已处理:11419 61 文件大小为:14608,当前已处理:14608 62 */ 63 64 ); 65 /解决上传文件名的中文乱码 66 upload.setHeaderEncoding(UTF-8); 67 /3、判断提交上来的数据是否是上传表单的数据 68 if(!ServletFileUpload.isMultipartContent(request) 69 /按照传统方式获取数据 70 return; 71 72 73 /设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB 74 upload.setFileSizeMax(1024*1024); 75 /设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB 76 upload.setSizeMax(1024*1024*10); 77 /4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List集合,每一个FileItem对应一个Form表单的输入项 78 List list = upload.parseRequest(request); 79 for(FileItem item : list) 80 /如果fileitem中封装的是普通输入项的数据 81 if(item.isFormField() 82 String name = item.getFieldName(); 83 /解决普通输入项的数据的中文乱码问题 84 String value = item.getString(UTF-8); 85 /value = new String(value.getBytes(iso8859-1),UTF-8); 86 System.out.println(name + = + value); 87 else/如果fileitem中封装的是上传文件 88 /得到上传的文件名称, 89 String filename = item.getName(); 90 System.out.println(filename); 91 if(filename=null | filename.trim().equals() 92 continue; 93 94 /注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如: c:ab1.txt,而有些只是单纯的文件名,如:1.txt 95 /处理获取到的上传文件的文件名的路径部分,只保留文件名部分 96 filename = filename.substring(filename.lastIndexOf()+1); 97 /得到上传文件的扩展名 98 String fileExtName = filename.substring(filename.lastIndexOf(.)+1); 99 /如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法100 System.out.println(上传的文件的扩展名是:+fileExtName);101 /获取item中的上传文件的输入流102 InputStream in = item.getInputStream();103 /得到文件保存的名称104 String saveFilename = makeFileName(filename);105 /得到文件的保存目录106 String realSavePath = makePath(saveFilename, savePath);107 /创建一个文件输出流108 FileOutputStream out = new FileOutputStream(realSavePath + + saveFilename);109 /创建一个缓冲区110 byte buffer = new byte1024;111 /判断输入流中的数据是否已经读完的标识112 int len = 0;113 /循环将输入流读入到缓冲区当中,(len=in.read(buffer)0就表示in里面还有数据114 while(len=in.read(buffer)0)115 /使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + + filename)当中116 out.write(buffer, 0, len);117 118 /关闭输入流119 in.close();120 /关闭输出流121 out.close();122 /删除处理文件上传时生成的临时文件123 /item.delete();124 message = 文件上传成功!;125 126 127 catch (FileUploadBase.FileSizeLimitExceededException e) 128 e.printStackTrace();129 request.setAttribute(message, 单个文件超出最大值!);130 request.getRequestDispatcher(/message.jsp).forward(request, response);131 return;132 catch (FileUploadBase.SizeLimitExceededException e) 133 e.printStackTrace();134 request.setAttribute(message, 上传文件的总的大小超出限制的最大值!);135 request.getRequestDispatcher(/message.jsp).forward(request, response);136 return;137 catch (Exception e) 138 message= 文件上传失败!;139 e.printStackTrace();140 141 request.setAttribute(message,message);142 request.getRequestDispatcher(/message.jsp).forward(request, response);143 144 145 /*146 * Method: makeFileName147 * Description: 生成上传文件的文件名,文件名以:uuid+_+文件的原始名称148 * Anthor:孤傲苍狼149 * param filename 文件的原始名称150 * return uuid+_+文件的原始名称151 */ 152 private String makeFileName(String filename) /2.jpg153 /为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名154 return UUID.randomUUID().toString() + _ + filename;155 156 157 /*158 * 为防止一个目录下面出现太多文件,要使用hash算法打散存储159 * Method: makePath160 * Description: 161 * Anthor:孤傲苍狼162 *163 * param filename 文件名,要根据文件名生成存储目录164 * param savePath 文件存储路径165 * return 新的存储目录166 */ 167 private String makePath(String filename,String savePath)168 /得到文件名的hashCode的值,得到的就是filename这个字符串对象在内存中的地址169 int hashcode = filename.hashCode();170 int dir1 = hashcode&0xf; /0-15171 int dir2 = (hashcode&0xf0)4; /0-15172 /构造新的保存目录173 String dir = savePath + + dir1 + + dir2; /upload23 upload35174 /File既可以代表文件也可以代表目录175 File file = new File(dir);176 /如果目录不存在177 if(!file.exists()178 /创建目录179 file.mkdirs();180 181 return dir;182 183 184 public void doPost(HttpServletRequest request, HttpServletResponse response)185 throws ServletException, IOException 186 187 doGet(request, response);188 189 针对上述提出的5点小细节问题进行改进之后,我们的文件上传功能就算是做得比较完善了。三、文件下载3.1、列出提供下载的文件资源我们要将Web应用系统中的文件资源提供给用户进行下载,首先我们要有一个页面列出上传文件目录下的所有文件,当用户点击文件下载超链接时就进行下载操作,编写一个ListFileServlet,用于列出Web应用系统中所有下载文件。ListFileServlet的代码如下: 1 package me.gacl.web.controller; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.util.HashMap; 6 import java.util.Map; 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest;10 import javax.servlet.http.HttpServletResponse;11 12 /*13 * ClassName: ListFileServlet14 * Description: 列出Web系统中所有下载文件15 * author: 孤傲苍狼16 * date: 2015-1-4 下午9:54:4017 *18 */ 19 public class ListFileServlet extends HttpServlet 20 21 public void doGet(HttpServletRequest request, HttpServletResponse response)22 throws ServletException, IOException 23 /获取上传文件的目录24 String uploadFilePath = this.getServletContext().getRealPath(/WEB-INF/upload);25 /存储要下载的文件名26 Map fileNameMap = new HashMap();27 /递归遍历filepath目录下的所有文件和目录,将文件的文件名存储到map集合中28 listfile(new File(uploadFilePath),fileNameMap);/File既可以代表一个文件也可以代表一个目录29 /将Map集合发送到listfile.jsp页面进行显示30 request.setAttribute(fileNameMap, fileNameMap);31 request.getRequestDispatcher(/listfile.jsp).forward(request, response);32 33 34 /*35 * Method: listfile36 * Description: 递归遍历指定目录下的所有文件37 * Anthor:孤傲苍

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论