e2

滴滴侠,fai抖

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

使用JSP/Servlet简单实现文件上传与下载

   通过学习黑马jsp教学视频,我学会了使用jsp与servlet简单地实现web的文件的上传与下载,首先感谢黑马。好了,下面来简单了解如何通过使用jsp与servlet实现文件上传与下载。
       在写代码之前,我们需要导入两个额外的jar包,一个是common-io-2.2.jar,另一个是commons-fileupload-1.3.1.jar,将这个两个jar 包导入WEB-INF/lib目录里。
       首先,想要在web端即网页上实现文件上传,必须要提供一个选择文件的框,即设置一个<input type="file"/>的元素,光有这个还不行,还需要对<input>元素外的表单form进行设置,将form的enctype属性设置为“multipart/form-data”,即<form action="" method="post" enctype="multipart/form-data">,当然请求方式也必须是post。让我们来简单做一个上传的jsp页面:
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2.   
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  4. <html>  
  5.   <head>  
  6.     <title>文件上传</title>  
  7.       
  8.     <meta http-equiv="pragma" content="no-cache">  
  9.     <meta http-equiv="cache-control" content="no-cache">  
  10.     <meta http-equiv="expires" content="0">  
  11.     <!-- 
  12.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  13.     -->  
  14.   
  15.   </head>  
  16.     
  17.   <body>  
  18.     <form action="${pageContext.request.contextPath}/servlet/UploadServlet" method="post" enctype="multipart/form-data">  
  19.         name:<input name="name"/><br/>  
  20.         file1:<input type="file" name="f1"/><br/>  
  21.           
  22.         <input type="submit" value="上传">  
  23.     </form>  
  24.   </body>  
  25. </html>  
       jsp页面做好之后,我们就要写一个UploadServlet,在编写上传servlet时,我们需要考虑到如果上传的文件出现重名的情况,以及上传的文件可能会出现的乱码情况,所以我们需要编码与客户端一致,并且根据文件名的hashcode计算存储目录,避免一个文件夹中的文件过多,当然为了保证服务器的安全,我们将存放文件的目录放在用户直接访问不到的地方,比如在WEB-INF文件夹下创建一个file文件夹。具体做法如下:
  1. public class UploadServlet extends HttpServlet {  
  2.   
  3.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  4.             throws ServletException, IOException {  
  5.         request.setCharacterEncoding("UTF-8");  
  6.         response.setContentType("text/html;charset=UTF-8");  
  7.         PrintWriter out = response.getWriter();  
  8.         System.out.print(request.getRemoteAddr());  
  9.         boolean isMultipart = ServletFileUpload.isMultipartContent(request);  
  10.         if(!isMultipart){  
  11.             throw new RuntimeException("请检查您的表单的enctype属性,确定是multipart/form-data");  
  12.         }  
  13.         DiskFileItemFactory dfif = new DiskFileItemFactory();  
  14.         ServletFileUpload parser = new ServletFileUpload(dfif);  
  15.           
  16.         parser.setFileSizeMax(3*1024*1024);//设置单个文件上传的大小  
  17.         parser.setSizeMax(6*1024*1024);//多文件上传时总大小限制  
  18.           
  19.         List<FileItem> items = null;  
  20.         try {  
  21.             items = parser.parseRequest(request);  
  22.         }catch(FileUploadBase.FileSizeLimitExceededException e) {  
  23.             out.write("上传文件超出了3M");  
  24.             return;  
  25.         }catch(FileUploadBase.SizeLimitExceededException e){  
  26.             out.write("总文件超出了6M");  
  27.             return;  
  28.         }catch (FileUploadException e) {  
  29.             e.printStackTrace();  
  30.             throw new RuntimeException("解析上传内容失败,请重新试一下");  
  31.         }  
  32.           
  33.         //处理请求内容  
  34.         if(items!=null){  
  35.             for(FileItem item:items){  
  36.                 if(item.isFormField()){  
  37.                     processFormField(item);  
  38.                 }else{  
  39.                     processUploadField(item);  
  40.                 }  
  41.             }  
  42.         }  
  43.           
  44.         out.write("上传成功!");  
  45.     }  
  46.     private void processUploadField(FileItem item) {  
  47.         try {  
  48.             String fileName = item.getName();  
  49.               
  50.               
  51.             //用户没有选择上传文件时  
  52.             if(fileName!=null&&!fileName.equals("")){  
  53.                 fileName = UUID.randomUUID().toString()+"_"+FilenameUtils.getName(fileName);  
  54.                   
  55.                 //扩展名  
  56.                 String extension = FilenameUtils.getExtension(fileName);  
  57.                 //MIME类型  
  58.                 String contentType = item.getContentType();  
  59.                   
  60.                   
  61.                   
  62.                 //分目录存储:日期解决  
  63.     //          Date now = new Date();  
  64.     //          DateFormat df = new SimpleDateFormat("yyyy-MM-dd");  
  65.     //            
  66.     //          String childDirectory  = df.format(now);  
  67.                   
  68.                   
  69.                 //按照文件名的hashCode计算存储目录  
  70.                 String childDirectory = makeChildDirectory(getServletContext().getRealPath("/WEB-INF/files/"),fileName);  
  71.                   
  72.                 String storeDirectoryPath = getServletContext().getRealPath("/WEB-INF/files/"+childDirectory);  
  73.                 File storeDirectory = new File(storeDirectoryPath);  
  74.                 if(!storeDirectory.exists()){  
  75.                     storeDirectory.mkdirs();  
  76.                 }  
  77.                 System.out.println(fileName);  
  78.                 item.write(new File(storeDirectoryPath+File.separator+fileName));//删除临时文件  
  79.                   
  80.             }  
  81.         } catch (Exception e) {  
  82.             throw new RuntimeException("上传失败,请重试");  
  83.         }  
  84.           
  85.     }  
  86.     //计算存放的子目录  
  87.     private String makeChildDirectory(String realPath, String fileName) {  
  88.         int hashCode = fileName.hashCode();  
  89.         int dir1 = hashCode&0xf;// 取1~4位  
  90.         int dir2 = (hashCode&0xf0)>>4;//取5~8位  
  91.           
  92.         String directory = ""+dir1+File.separator+dir2;  
  93.         File file = new File(realPath,directory);  
  94.         if(!file.exists())  
  95.             file.mkdirs();  
  96.           
  97.         return directory;  
  98.     }  
  99.     private void processFormField(FileItem item) {  
  100.         String fieldName = item.getFieldName();//字段名  
  101.         String fieldValue;  
  102.         try {  
  103.             fieldValue = item.getString("UTF-8");  
  104.         } catch (UnsupportedEncodingException e) {  
  105.             throw new RuntimeException("不支持UTF-8编码");  
  106.         }  
  107.         System.out.println(fieldName+"="+fieldValue);  
  108.     }  
  109.   
  110.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  111.             throws ServletException, IOException {  
  112.         doGet(request, response);  
  113.     }  
  114.   
  115. }  

      至此,上传的任务就基本完成了,有了上传当然也要有下载功能,在下载之前,我们需要将所有已经上传的文件显示在网页上,通过一个servlet与一个jsp页面来显示,servlet代码如下:
  1. public class ShowAllFilesServlet extends HttpServlet {  
  2.   
  3.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  4.             throws ServletException, IOException {  
  5.         String storeDirectory = getServletContext().getRealPath("/WEB-INF/files");  
  6.         File root = new File(storeDirectory);  
  7.           
  8.         //用Map保存递归的文件名:key:UUID文件名   value:老文件名  
  9.         Map<String, String> map = new HashMap<String, String>();  
  10.         treeWalk(root,map);  
  11.           
  12.         request.setAttribute("map", map);  
  13.         request.getRequestDispatcher("/listFiles.jsp").forward(request, response);  
  14.     }  
  15.     //递归,把文件名放到Map中  
  16.     private void treeWalk(File root, Map<String, String> map) {  
  17.         if(root.isFile()){  
  18.             String fileName = root.getName();//文件名       
  19.             String oldFileName = fileName.substring(fileName.indexOf("_")+1);  
  20.             map.put(fileName, oldFileName);  
  21.         }else{  
  22.             File fs[] = root.listFiles();  
  23.             for(File file:fs){  
  24.                 treeWalk(file, map);  
  25.             }  
  26.         }  
  27.           
  28.     }  
  29.   
  30.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  31.             throws ServletException, IOException {  
  32.         doGet(request, response);  
  33.     }  
  34.   
  35. }  
       通过上面的servlet转发到listFiles.jsp页面,listFiles.jsp页面:
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  4. <html>  
  5.   <head>  
  6.     <title>title</title>  
  7.       
  8.     <meta http-equiv="pragma" content="no-cache">  
  9.     <meta http-equiv="cache-control" content="no-cache">  
  10.     <meta http-equiv="expires" content="0">  
  11.     <!--  
  12.     <link rel="stylesheet" type="text/css" href="styles.css">  
  13.     -->  
  14.   
  15.   </head>  
  16.     
  17.   <body>  
  18.     <h1>以下资源可供下载</h1>  
  19.     <c:forEach items="${map}" var="me">  
  20.         <c:url value="/servlet/DownloadServlet" var="url">  
  21.             <c:param name="filename" value="${me.key}"></c:param>  
  22.         </c:url>  
  23.         ${me.value}  <a href="${url}">下载</a><br/>  
  24.     </c:forEach>  
  25.   </body>  
  26. </html>  

      到这里,文件也显示出来了,就需要点击下载进行下载文件了,最后一步,我们再编写一个DownloadServlet:
  1. public class DownloadServlet extends HttpServlet {  
  2.   
  3.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  4.             throws ServletException, IOException {  
  5.         String uuidfilename = request.getParameter("filename");//get方式提交的  
  6.         uuidfilename = new String(uuidfilename.getBytes("ISO-8859-1"),"UTF-8");//UUID的文件名  
  7.           
  8.         String storeDirectory = getServletContext().getRealPath("/WEB-INF/files");  
  9.         //得到存放的子目录  
  10.         String childDirecotry = makeChildDirectory(storeDirectory, uuidfilename);  
  11.           
  12.         //构建输入流  
  13.         InputStream in = new FileInputStream(storeDirectory+File.separator+childDirecotry+File.separator+uuidfilename);  
  14.         //下载  
  15.         String oldfilename = uuidfilename.substring(uuidfilename.indexOf("_")+1);  
  16.         //通知客户端以下载的方式打开  
  17.         response.setHeader("Content-Disposition""attachment;filename="+URLEncoder.encode(oldfilename, "UTF-8"));  
  18.           
  19.         OutputStream out = response.getOutputStream();  
  20.           
  21.         int len = -1;  
  22.         byte b[] = new byte[1024];  
  23.         while((len=in.read(b))!=-1){  
  24.             out.write(b,0,len);  
  25.         }  
  26.         in.close();  
  27.         out.close();  
  28.           
  29.     }  
  30.   
  31.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  32.             throws ServletException, IOException {  
  33.         doGet(request, response);  
  34.     }  
  35.     //计算存放的子目录  
  36.     private String makeChildDirectory(String realPath, String fileName) {  
  37.         int hashCode = fileName.hashCode();  
  38.         int dir1 = hashCode&0xf;// 取1~4位  
  39.         int dir2 = (hashCode&0xf0)>>4;//取5~8位  
  40.           
  41.         String directory = ""+dir1+File.separator+dir2;  
  42.         File file = new File(realPath,directory);  
  43.         if(!file.exists())  
  44.             file.mkdirs();  
  45.           
  46.         return directory;  
  47.     }  
  48. }  

      文件上传与下载就已经全部完成了。

     
posted on 2017-03-20 11:04  纯黑Se丶  阅读(491)  评论(0编辑  收藏  举报