zoukankan      html  css  js  c++  java
  • 使用jsp/servlet简单实现文件上传与下载

    使用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页面:
     
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
      
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
    <html>  
      <head>  
        <title>文件上传</title>  
          
        <meta http-equiv="pragma" content="no-cache">  
        <meta http-equiv="cache-control" content="no-cache">  
        <meta http-equiv="expires" content="0">  
        <!-- 
        <link rel="stylesheet" type="text/css" href="styles.css"> 
        -->  
      
      </head>  
        
      <body>  
        <form action="${pageContext.request.contextPath}/servlet/UploadServlet" method="post" enctype="multipart/form-data">  
            name:<input name="name"/><br/>  
            file1:<input type="file" name="f1"/><br/>  
              
            <input type="submit" value="上传">  
        </form>  
      </body>  
    </html>  

     jsp页面做好之后,我们就要写一个UploadServlet,在编写上传servlet时,我们需要考虑到如果上传的文件出现重名的情况,以及上传的文件可能会出现的乱码情况,所以我们需要编码与客户端一致,并且根据文件名的hashcode计算存储目录,避免一个文件夹中的文件过多,当然为了保证服务器的安全,我们将存放文件的目录放在用户直接访问不到的地方,比如在WEB-INF文件夹下创建一个file文件夹。具体做法如下:

    public class UploadServlet extends HttpServlet {  
      
        public void doGet(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
            request.setCharacterEncoding("UTF-8");  
            response.setContentType("text/html;charset=UTF-8");  
            PrintWriter out = response.getWriter();  
            System.out.print(request.getRemoteAddr());  
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);  
            if(!isMultipart){  
                throw new RuntimeException("请检查您的表单的enctype属性,确定是multipart/form-data");  
            }  
            DiskFileItemFactory dfif = new DiskFileItemFactory();  
            ServletFileUpload parser = new ServletFileUpload(dfif);  
              
            parser.setFileSizeMax(3*1024*1024);//设置单个文件上传的大小  
            parser.setSizeMax(6*1024*1024);//多文件上传时总大小限制  
              
            List<FileItem> items = null;  
            try {  
                items = parser.parseRequest(request);  
            }catch(FileUploadBase.FileSizeLimitExceededException e) {  
                out.write("上传文件超出了3M");  
                return;  
            }catch(FileUploadBase.SizeLimitExceededException e){  
                out.write("总文件超出了6M");  
                return;  
            }catch (FileUploadException e) {  
                e.printStackTrace();  
                throw new RuntimeException("解析上传内容失败,请重新试一下");  
            }  
              
            //处理请求内容  
            if(items!=null){  
                for(FileItem item:items){  
                    if(item.isFormField()){  
                        processFormField(item);  
                    }else{  
                        processUploadField(item);  
                    }  
                }  
            }  
              
            out.write("上传成功!");  
        }  
        private void processUploadField(FileItem item) {  
            try {  
                String fileName = item.getName();  
                  
                  
                //用户没有选择上传文件时  
                if(fileName!=null&&!fileName.equals("")){  
                    fileName = UUID.randomUUID().toString()+"_"+FilenameUtils.getName(fileName);  
                      
                    //扩展名  
                    String extension = FilenameUtils.getExtension(fileName);  
                    //MIME类型  
                    String contentType = item.getContentType();  
                      
                      
                      
                    //分目录存储:日期解决  
        //          Date now = new Date();  
        //          DateFormat df = new SimpleDateFormat("yyyy-MM-dd");  
        //            
        //          String childDirectory  = df.format(now);  
                      
                      
                    //按照文件名的hashCode计算存储目录  
                    String childDirectory = makeChildDirectory(getServletContext().getRealPath("/WEB-INF/files/"),fileName);  
                      
                    String storeDirectoryPath = getServletContext().getRealPath("/WEB-INF/files/"+childDirectory);  
                    File storeDirectory = new File(storeDirectoryPath);  
                    if(!storeDirectory.exists()){  
                        storeDirectory.mkdirs();  
                    }  
                    System.out.println(fileName);  
                    item.write(new File(storeDirectoryPath+File.separator+fileName));//删除临时文件  
                      
                }  
            } catch (Exception e) {  
                throw new RuntimeException("上传失败,请重试");  
            }  
              
        }  
        //计算存放的子目录  
        private String makeChildDirectory(String realPath, String fileName) {  
            int hashCode = fileName.hashCode();  
            int dir1 = hashCode&0xf;// 取1~4位  
            int dir2 = (hashCode&0xf0)>>4;//取5~8位  
              
            String directory = ""+dir1+File.separator+dir2;  
            File file = new File(realPath,directory);  
            if(!file.exists())  
                file.mkdirs();  
              
            return directory;  
        }  
        private void processFormField(FileItem item) {  
            String fieldName = item.getFieldName();//字段名  
            String fieldValue;  
            try {  
                fieldValue = item.getString("UTF-8");  
            } catch (UnsupportedEncodingException e) {  
                throw new RuntimeException("不支持UTF-8编码");  
            }  
            System.out.println(fieldName+"="+fieldValue);  
        }  
      
        public void doPost(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
            doGet(request, response);  
        }  
      
    }  

     至此,上传的任务就基本完成了,有了上传当然也要有下载功能,在下载之前,我们需要将所有已经上传的文件显示在网页上,通过一个servlet与一个jsp页面来显示,servlet代码如下:

    public class ShowAllFilesServlet extends HttpServlet {  
      
        public void doGet(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
            String storeDirectory = getServletContext().getRealPath("/WEB-INF/files");  
            File root = new File(storeDirectory);  
              
            //用Map保存递归的文件名:key:UUID文件名   value:老文件名  
            Map<String, String> map = new HashMap<String, String>();  
            treeWalk(root,map);  
              
            request.setAttribute("map", map);  
            request.getRequestDispatcher("/listFiles.jsp").forward(request, response);  
        }  
        //递归,把文件名放到Map中  
        private void treeWalk(File root, Map<String, String> map) {  
            if(root.isFile()){  
                String fileName = root.getName();//文件名       
                String oldFileName = fileName.substring(fileName.indexOf("_")+1);  
                map.put(fileName, oldFileName);  
            }else{  
                File fs[] = root.listFiles();  
                for(File file:fs){  
                    treeWalk(file, map);  
                }  
            }  
              
        }  
      
        public void doPost(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
            doGet(request, response);  
        }  
      
    }  

     通过上面的servlet转发到listFiles.jsp页面,listFiles.jsp页面:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
    <html>  
      <head>  
        <title>title</title>  
          
        <meta http-equiv="pragma" content="no-cache">  
        <meta http-equiv="cache-control" content="no-cache">  
        <meta http-equiv="expires" content="0">  
        <!--  
        <link rel="stylesheet" type="text/css" href="styles.css">  
        -->  
      
      </head>  
        
      <body>  
        <h1>以下资源可供下载</h1>  
        <c:forEach items="${map}" var="me">  
            <c:url value="/servlet/DownloadServlet" var="url">  
                <c:param name="filename" value="${me.key}"></c:param>  
            </c:url>  
            ${me.value}  <a href="${url}">下载</a><br/>  
        </c:forEach>  
      </body>  
    </html>  

     到这里,文件也显示出来了,就需要点击下载进行下载文件了,最后一步,我们再编写一个DownloadServlet:

    public class DownloadServlet extends HttpServlet {  
      
        public void doGet(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
            String uuidfilename = request.getParameter("filename");//get方式提交的  
            uuidfilename = new String(uuidfilename.getBytes("ISO-8859-1"),"UTF-8");//UUID的文件名  
              
            String storeDirectory = getServletContext().getRealPath("/WEB-INF/files");  
            //得到存放的子目录  
            String childDirecotry = makeChildDirectory(storeDirectory, uuidfilename);  
              
            //构建输入流  
            InputStream in = new FileInputStream(storeDirectory+File.separator+childDirecotry+File.separator+uuidfilename);  
            //下载  
            String oldfilename = uuidfilename.substring(uuidfilename.indexOf("_")+1);  
            //通知客户端以下载的方式打开  
            response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(oldfilename, "UTF-8"));  
              
            OutputStream out = response.getOutputStream();  
              
            int len = -1;  
            byte b[] = new byte[1024];  
            while((len=in.read(b))!=-1){  
                out.write(b,0,len);  
            }  
            in.close();  
            out.close();  
              
        }  
      
        public void doPost(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
            doGet(request, response);  
        }  
        //计算存放的子目录  
        private String makeChildDirectory(String realPath, String fileName) {  
            int hashCode = fileName.hashCode();  
            int dir1 = hashCode&0xf;// 取1~4位  
            int dir2 = (hashCode&0xf0)>>4;//取5~8位  
              
            String directory = ""+dir1+File.separator+dir2;  
            File file = new File(realPath,directory);  
            if(!file.exists())  
                file.mkdirs();  
              
            return directory;  
        }  
    }  

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

    本文来源于 http://blog.csdn.net/wetsion/article/details/50890031

  • 相关阅读:
    windows下面Nginx日志切割
    C#通过DocX创建word
    leetcode 189 Rotate Array
    leetcode 172 Factorial Trailing Zeroes
    leetcode 169 Majority Element 冰山查询
    leetcode 165 Compare Version Numbers
    leetcode 160 Intersection of Two Linked Lists
    【windows-》linux】SCP
    【设计】B端和C端区别
    【Flask】部署
  • 原文地址:https://www.cnblogs.com/ys-wuhan/p/5772426.html
Copyright © 2011-2022 走看看