zoukankan      html  css  js  c++  java
  • java web--文件上传下载 (1)

     1.文件上传分析

    文件上传: 就是将客户端的数据发送到服务器上
    文件上传要求:
                浏览器端要求:
                                        1.表单提交方式 post
                                        2.提供文件上传框(组件) input type="file"
                                        3.表单entype属性必须为 multipart/form-data
                 服务器端要求:
                                        request.getInputStream()
                 注意:
                                若表单使用了 multipart/form-data ,使用原生request.getParameter去获取参数的时候都为null ,请求头有请求类型context-type:multipart/form-data 

                               因此要用流接收  ServletInputStream servletInputStream=request.getInputStream();

                               

                                 由于解析太过复杂,因此 使用工具类或者框架去解析用户上传的内容
                                   commons-fileupload,struts(底层:commons-fileupload),serlvet3.0
                                  apache出品的一款专门处理文件上传的工具类  commons-fileupload

                  上传注意问题:
                                    1.文件名称  浏览器不同,有可能获取的名称不同, 1.txt 或者 G:1.txt 
                                    2.文件重名  给文件来一个随机名称 uuid方式  毫米值+三个随机数
                                      数据库中可以存放多个字段: 文件名称和文件路径
                                     文件名称:身份证正面.jpg
                                     文件路径:g:123123123423sfsf.jpg
                                     文件下载:  response.setHeader("content-disposition","attachment;filename="+真实名称);
                                    3.文件安全(fastDFS框架)  安全目录:web-inf meta-inf 项目之外的目录
                                       不安全目录:项目目录(除去web-inf和meta-inf)
                                   4.目录分离常用的方式:解决一个文件夹放1万个数据下载慢的问题
                                      按用户划分、按时间划分、按数量划分、随机划分 
    2.文件上传实现 

                  

    <%@ 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>
    </head>
    <body>
        <form action="${pageContext.request.contextPath}/fileServlet" method="post" enctype="multipart/form-data"> 
            <input type="file" name="file1"/>
            <input type="file" name="file2"/>
            <input type="text" name="username"/>
            <input type="submit" value="提交">
        </form>      
    </body>
    </html>
    index.jsp 上传页面
    <%@ page language="java" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML>
    <html>
      <head>
        <title>消息提示</title>
      </head>
      
      <body>
            ${message}
      </body>
    </html>
    message 上传成功返回的页面
    package com.zwj.demo;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    import javax.servlet.ServletException;
    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;
    
    
    /**
     * 上传功能
     */
    public class fileServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        @Override
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                        //得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
                        System.out.println(this.getServletName()); 
                        System.out.println(this.getServletInfo());
                        String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
                        File file = new File(savePath);
                        //判断上传文件的保存目录是否存在
                        if (!file.exists() && !file.isDirectory()) {
                            System.out.println(savePath+"目录不存在,需要创建");
                            //创建目录
                            file.mkdir();
                        }
                        //消息提示
                        String message = "";
                        try{
                            //使用Apache文件上传组件处理文件上传步骤:
                            //1、创建一个DiskFileItemFactory工厂
                            DiskFileItemFactory factory = new DiskFileItemFactory();
                            //2、创建一个文件上传解析器
                            ServletFileUpload upload = new ServletFileUpload(factory);
                             //解决上传文件名的中文乱码
                            upload.setHeaderEncoding("UTF-8"); 
                            //3、判断提交上来的数据是否是上传表单的数据
                            if(!ServletFileUpload.isMultipartContent(request)){
                                //按照传统方式获取数据
                                return;
                            }
                            //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
                            List<FileItem> list = upload.parseRequest(request);
                            for(FileItem item : list){
                                //如果fileitem中封装的是普通输入项的数据
                                if(item.isFormField()){
                                    String name = item.getFieldName();
                                    //解决普通输入项的数据的中文乱码问题
                                    String value = item.getString("UTF-8");
                                    //value = new String(value.getBytes("iso8859-1"),"UTF-8");
                                    System.out.println(name + "=" + value);
                                }else{//如果fileitem中封装的是上传文件
                                    //得到上传的文件名称,
                                    String filename = item.getName();
                                    System.out.println(filename);
                                    if(filename==null || filename.trim().equals("")){
                                        continue;
                                    }
                                    //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  c:a1.txt,而有些只是单纯的文件名,如:1.txt
                                    //处理获取到的上传文件的文件名的路径部分,只保留文件名部分
                                    filename = filename.substring(filename.lastIndexOf("\")+1);
                                    //获取item中的上传文件的输入流
                                    InputStream in = item.getInputStream();
                                    //创建一个文件输出流
                                    FileOutputStream out = new FileOutputStream(savePath + "\" + filename);
                                    //创建一个缓冲区
                                    byte buffer[] = new byte[1024];
                                    //判断输入流中的数据是否已经读完的标识
                                    int len = 0;
                                    //循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
                                    while((len=in.read(buffer))>0){
                                        //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\" + filename)当中
                                        out.write(buffer, 0, len);
                                    }
                                    //关闭输入流
                                    in.close();
                                    //关闭输出流
                                    out.close();
                                    //删除处理文件上传时生成的临时文件
                                    item.delete();
                                    message = "文件上传成功!";
                                }
                            }
                        }catch (Exception e) {
                            message= "文件上传失败!";
                            e.printStackTrace();
                            
                        }
                        request.setAttribute("message",message);
                        request.getRequestDispatcher("/message.jsp").forward(request, response);
            }
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
             /*
              * 表单提交时如果没有加 enctype="multipart/form-data",可以接受,但只是name的属性值
              * 加上后,使用request.getParameter("username") 为 null;
              * 因此要用流接收
              */
             //String username=request.getParameter("username");
              //String filename=request.getParameter("filesname");
             //  ServletInputStream servletInputStream=request.getInputStream();
             // System.out.println(servletInputStream);
              //org.apache.catalina.connector.CoyoteInputStream@18906123
              this.doGet(request, response);
            
        }
    }
    fileServlet 上传功能控制类

       2.2、上述的代码虽然可以成功将文件上传到服务器上面的指定目录中,但是文件上传功能有许多需要注意的小细节问题,以下的几点特别注意的

      1、为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。

      2、为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名。

      3、为防止一个目录下面出现太多文件,要使用hash算法打散存储。

      4、要限制上传文件的最大值。

      5、要限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。

      针对上述提出的5点细节问题,我们来改进一下UploadHandleServlet,改进后的代码如下:

    package com.zwj.demo;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    import java.util.UUID;
    
    import javax.servlet.ServletException;
    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.FileUploadBase;
    import org.apache.commons.fileupload.ProgressListener;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    
    
    /**
     * 上传下载功能
     */
    public class fileServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
        @Override
          public void doGet(HttpServletRequest request, HttpServletResponse response)
                 throws ServletException, IOException {
                     //得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
                     String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
                     //上传时生成的临时文件保存目录
                     String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
                     File tmpFile = new File(tempPath);
                     if (!tmpFile.exists()) {
                         //创建临时目录
                         tmpFile.mkdir();
                     }
                     //消息提示
                     String message = "";
                     try{
                         //使用Apache文件上传组件处理文件上传步骤:
                         //1、创建一个DiskFileItemFactory工厂
                         DiskFileItemFactory factory = new DiskFileItemFactory();
                         //设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。
                         factory.setSizeThreshold(1024*100);//设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB
                         //设置上传时生成的临时文件的保存目录
                         factory.setRepository(tmpFile);
                         //2、创建一个文件上传解析器
                         ServletFileUpload upload = new ServletFileUpload(factory);
                         //监听文件上传进度
                         upload.setProgressListener(new ProgressListener(){
                             public void update(long pBytesRead, long pContentLength, int arg2) {
                                 System.out.println("文件大小为:" + pContentLength + ",当前已处理:" + pBytesRead);
                                 /**
                                  * 文件大小为:14608,当前已处理:4096
                                     文件大小为:14608,当前已处理:7367
                                     文件大小为:14608,当前已处理:11419
                                     文件大小为:14608,当前已处理:14608
                                  */
                             }
                         });
                          //解决上传文件名的中文乱码
                         upload.setHeaderEncoding("UTF-8"); 
                         //3、判断提交上来的数据是否是上传表单的数据
                         if(!ServletFileUpload.isMultipartContent(request)){
                             //按照传统方式获取数据
                             return;
                         }
                         
                         //设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB
                         upload.setFileSizeMax(1024*1024);
                         //设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB
                         upload.setSizeMax(1024*1024*10);
                         //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
                         List<FileItem> list = upload.parseRequest(request);
                         for(FileItem item : list){
                             //如果fileitem中封装的是普通输入项的数据
                             if(item.isFormField()){
                                 String name = item.getFieldName();
                                 //解决普通输入项的数据的中文乱码问题
                                 String value = item.getString("UTF-8");
                                 //value = new String(value.getBytes("iso8859-1"),"UTF-8");
                                 System.out.println(name + "=" + value);
                             }else{//如果fileitem中封装的是上传文件
                                 //得到上传的文件名称,
                                 String filename = item.getName();
                                 System.out.println(filename);
                                 if(filename==null || filename.trim().equals("")){
                                     continue;
                                 }
                                 //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  c:a1.txt,而有些只是单纯的文件名,如:1.txt
                                 //处理获取到的上传文件的文件名的路径部分,只保留文件名部分
                                 filename = filename.substring(filename.lastIndexOf("\")+1);
                                 //得到上传文件的扩展名
                                 String fileExtName = filename.substring(filename.lastIndexOf(".")+1);
                                 //如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法
                                 System.out.println("上传的文件的扩展名是:"+fileExtName);
                                 //获取item中的上传文件的输入流
                                 InputStream in = item.getInputStream();
                                 //得到文件保存的名称
                                 String saveFilename = makeFileName(filename);
                                 //得到文件的保存目录
                                 String realSavePath = makePath(saveFilename, savePath);
                                 System.out.println(realSavePath + "\" + saveFilename);
                                 //创建一个文件输出流
                                 FileOutputStream out = new FileOutputStream(realSavePath + "\" + saveFilename);
                                 //创建一个缓冲区
                                 byte buffer[] = new byte[1024];
                                 //判断输入流中的数据是否已经读完的标识
                                 int len = 0;
                                 //循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
                                 while((len=in.read(buffer))>0){
                                     //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\" + filename)当中
                                     out.write(buffer, 0, len);
                                 }
                                 //关闭输入流
                                 in.close();
                                 //关闭输出流
                                 out.close();
                                 //删除处理文件上传时生成的临时文件
                                 //item.delete();
                                 message = "文件上传成功!";
                             }
                         }
                     }catch (FileUploadBase.FileSizeLimitExceededException e) {
                         e.printStackTrace();
                         request.setAttribute("message", "单个文件超出最大值!!!");
                         request.getRequestDispatcher("/message.jsp").forward(request, response);
                         return;
                     }catch (FileUploadBase.SizeLimitExceededException e) {
                         e.printStackTrace();
                         request.setAttribute("message", "上传文件的总的大小超出限制的最大值!!!");
                         request.getRequestDispatcher("/message.jsp").forward(request, response);
                         return;
                     }catch (Exception e) {
                         message= "文件上传失败!";
                         e.printStackTrace();
                     }
                     request.setAttribute("message",message);
                     request.getRequestDispatcher("/message.jsp").forward(request, response);
         }
         
         /**
         * @Method: makeFileName
         * @Description: 生成上传文件的文件名,文件名以:uuid+"_"+文件的原始名称
         * @param filename 文件的原始名称
         * @return uuid+"_"+文件的原始名称
         */ 
         private String makeFileName(String filename){  //2.jpg
             //为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名
             return UUID.randomUUID().toString() + "_" + filename;
         }
         
         /**
          * 为防止一个目录下面出现太多文件,要使用hash算法打散存储
         * @Method: makePath
         * @Description: 
         * @param filename 文件名,要根据文件名生成存储目录
         * @param savePath 文件存储路径
         * @return 新的存储目录
         */ 
         private String makePath(String filename,String savePath){
             //得到文件名的hashCode的值,得到的就是filename这个字符串对象在内存中的地址
             int hashcode = filename.hashCode();
             int dir1 = hashcode&0xf;  //0--15
             int dir2 = (hashcode&0xf0)>>4;  //0-15
             //构造新的保存目录
             String dir = savePath + "\" + dir1 + "\" + dir2;  //upload23  upload35
             //File既可以代表文件也可以代表目录
             File file = new File(dir);
             //如果目录不存在
             if(!file.exists()){
                 //创建目录
                 file.mkdirs();
             }
             return dir;
         }
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
             /*
              * 表单提交时如果没有加 enctype="multipart/form-data",可以接受,但只是name的属性值
              * 加上后,使用request.getParameter("username") 为 null;
              * 因此要用流接收
              */
             //String username=request.getParameter("username");
              //String filename=request.getParameter("filesname");
             //  ServletInputStream servletInputStream=request.getInputStream();
             // System.out.println(servletInputStream);
              //org.apache.catalina.connector.CoyoteInputStream@18906123
              this.doGet(request, response);
            
        }
    }
    /*文件大小为:87999,当前已处理:4096
    文件大小为:87999,当前已处理:7600
    文件大小为:87999,当前已处理:11652
    文件大小为:87999,当前已处理:15200
    文件大小为:87999,当前已处理:19252
    文件大小为:87999,当前已处理:22800
    文件大小为:87999,当前已处理:26852
    文件大小为:87999,当前已处理:30400
    文件大小为:87999,当前已处理:34452
    文件大小为:87999,当前已处理:38000
    文件大小为:87999,当前已处理:42052
    文件大小为:87999,当前已处理:45600
    文件大小为:87999,当前已处理:49652
    文件大小为:87999,当前已处理:53200
    文件大小为:87999,当前已处理:57252
    文件大小为:87999,当前已处理:60800
    文件大小为:87999,当前已处理:64852
    文件大小为:87999,当前已处理:68400
    文件大小为:87999,当前已处理:72452
    文件大小为:87999,当前已处理:76000
    文件大小为:87999,当前已处理:80052
    文件大小为:87999,当前已处理:83600
    文件大小为:87999,当前已处理:87652
    文件大小为:87999,当前已处理:87999
    下载必看.doc
    上传的文件的扩展名是:doc
    D:workspace.metadata.pluginsorg.eclipse.wst.server.core	mp0wtpwebappsfileUploadWEB-INFupload101ee18e49-8fad-434e-aad7-6c2e08284cfc_下载必看.doc
    CookUtils.java
    上传的文件的扩展名是:java
    D:workspace.metadata.pluginsorg.eclipse.wst.server.core	mp0wtpwebappsfileUploadWEB-INFupload11a0fab1db-9e30-4475-8f96-c42f4c8714ae_CookUtils.java
    username=name
    */
    fileServlet 上传功能修改后的

     3.文件下载

                              

         首先 http://localhost:8080/fileUpload/listFileServlet 得到服务器可以下载文件  注:用jstl标签 必须有jstl.jar / standard.jar 两个jar包

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
       <head>
         <title>下载文件显示页面</title>
       </head>
       
       <body>
           <!-- 遍历Map集合    k :a0fab1db-9e30-4475-8f96-c42f4c8714ae_CookUtils.java  
              v:CookUtils.java
               -->
         <c:forEach var="me" items="${fileNameMap}">
             <c:url value="/downLoadServlet" var="downurl">
                 <c:param name="filename" value="${me.key}"></c:param>
             </c:url>
             ${me.value}<a href="${downurl}">下载</a>
             <br/>
         </c:forEach>
       </body>
     </html>
    listfile.jsp
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
      <display-name>fileUpload</display-name>
       <!--上传的servlet-->
       <servlet>
             <servlet-name>user</servlet-name>
             <servlet-class>com.zwj.demo.fileServlet</servlet-class>
       </servlet>
      <servlet-mapping>
             <servlet-name>user</servlet-name>
          <url-pattern>/fileServlet</url-pattern>      
      </servlet-mapping>
       <!--读取可下载文件的servlet-->
       <servlet>
          <servlet-name>ListFileServlet</servlet-name>
          <servlet-class>com.zwj.demo.ListFileServlet</servlet-class>
       </servlet>
      <servlet-mapping>
          <servlet-name>ListFileServlet</servlet-name>
         <url-pattern>/listFileServlet</url-pattern>
      </servlet-mapping> 
    <!--下载的servlet-->
      <servlet>
          <servlet-name>DownLoadServlet</servlet-name>
          <servlet-class>com.zwj.demo.DownLoadServlet</servlet-class>
    </servlet>
     
    <servlet-mapping>
          <servlet-name>DownLoadServlet</servlet-name>
          <url-pattern>/downLoadServlet</url-pattern>
    </servlet-mapping>
     
      
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
      
      
    </web-app>
    web.xml
    package com.zwj.demo;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.URLEncoder;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class DownLoadServlet extends HttpServlet {
         public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                //得到要下载的文件名
                String fileName = request.getParameter("filename");  //23239283-92489-阿凡达.avi
                fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
                //上传的文件都是保存在/WEB-INF/upload目录下的子目录当中
                String fileSaveRootPath=this.getServletContext().getRealPath("/WEB-INF/upload");
                //通过文件名找出文件的所在目录
                String path = findFileSavePathByFileName(fileName,fileSaveRootPath);
                //得到要下载的文件
                File file = new File(path + "\" + fileName);
                //如果文件不存在
                if(!file.exists()){
                    request.setAttribute("message", "您要下载的资源已被删除!!");
                    request.getRequestDispatcher("/message.jsp").forward(request, response);
                    return;
                }
                //处理文件名
                String realname = fileName.substring(fileName.indexOf("_")+1);
                //设置响应头,控制浏览器下载该文件
                response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
                //读取要下载的文件,保存到文件输入流
                FileInputStream in = new FileInputStream(path + "\" + fileName);
                //创建输出流
                OutputStream out = response.getOutputStream();
                //创建缓冲区
                byte buffer[] = new byte[1024];
                int len = 0;
                //循环将输入流中的内容读取到缓冲区当中
                while((len=in.read(buffer))>0){
                    //输出缓冲区的内容到浏览器,实现文件下载
                    out.write(buffer, 0, len);
                }
                //关闭文件输入流
                in.close();
                //关闭输出流
                out.close();
            }
            
            /**
            * @Method: findFileSavePathByFileName
            * @Description: 通过文件名和存储上传文件根目录找出要下载的文件的所在路径
            * @param filename 要下载的文件名
            * @param saveRootPath 上传文件保存的根目录,也就是/WEB-INF/upload目录
            * @return 要下载的文件的存储目录
            */ 
            public String findFileSavePathByFileName(String filename,String saveRootPath){
                int hashcode = filename.hashCode();
                int dir1 = hashcode&0xf;  //0--15
                int dir2 = (hashcode&0xf0)>>4;  //0-15
                String dir = saveRootPath + "\" + dir1 + "\" + dir2;  //upload23  upload35
                File file = new File(dir);
                if(!file.exists()){
                    //创建目录
                    file.mkdirs();
                }
                return dir;
            }
            
            public void doPost(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                doGet(request, response);
            }
    }
    DownLoadServlet  下载文件servlet
     1package me.gacl.web.controller;
     2 
     3 import java.io.File;
     4 import java.io.FileInputStream;
     5 import java.io.IOException;
     6 import java.io.OutputStream;
     7 import java.net.URLEncoder;
     8 import javax.servlet.ServletException;
     9 import javax.servlet.http.HttpServlet;
    10 import javax.servlet.http.HttpServletRequest;
    11 import javax.servlet.http.HttpServletResponse;
    12 
    13 public class DownLoadServlet extends HttpServlet {
    14 
    15     
    16     public void doGet(HttpServletRequest request, HttpServletResponse response)
    17             throws ServletException, IOException {
    18         //得到要下载的文件名
    19         String fileName = request.getParameter("filename");  //23239283-92489-阿凡达.avi
    20         fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
    21         //上传的文件都是保存在/WEB-INF/upload目录下的子目录当中
    22         String fileSaveRootPath=this.getServletContext().getRealPath("/WEB-INF/upload");
    23         //通过文件名找出文件的所在目录
    24         String path = findFileSavePathByFileName(fileName,fileSaveRootPath);
    25         //得到要下载的文件
    26         File file = new File(path + "\" + fileName);
    27         //如果文件不存在
    28         if(!file.exists()){
    29             request.setAttribute("message", "您要下载的资源已被删除!!");
    30             request.getRequestDispatcher("/message.jsp").forward(request, response);
    31             return;
    32         }
    33         //处理文件名
    34         String realname = fileName.substring(fileName.indexOf("_")+1);
    35         //设置响应头,控制浏览器下载该文件
    36         response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
    37         //读取要下载的文件,保存到文件输入流
    38         FileInputStream in = new FileInputStream(path + "\" + fileName);
    39         //创建输出流
    40         OutputStream out = response.getOutputStream();
    41         //创建缓冲区
    42         byte buffer[] = new byte[1024];
    43         int len = 0;
    44         //循环将输入流中的内容读取到缓冲区当中
    45         while((len=in.read(buffer))>0){
    46             //输出缓冲区的内容到浏览器,实现文件下载
    47             out.write(buffer, 0, len);
    48         }
    49         //关闭文件输入流
    50         in.close();
    51         //关闭输出流
    52         out.close();
    53     }
    54     
    55     /**
    56     * @Method: findFileSavePathByFileName
    57     * @Description: 通过文件名和存储上传文件根目录找出要下载的文件的所在路径
    58     * @Anthor:孤傲苍狼
    59     * @param filename 要下载的文件名
    60     * @param saveRootPath 上传文件保存的根目录,也就是/WEB-INF/upload目录
    61     * @return 要下载的文件的存储目录
    62     */ 
    63     public String findFileSavePathByFileName(String filename,String saveRootPath){
    64         int hashcode = filename.hashCode();
    65         int dir1 = hashcode&0xf;  //0--15
    66         int dir2 = (hashcode&0xf0)>>4;  //0-15
    67         String dir = saveRootPath + "\" + dir1 + "\" + dir2;  //upload23  upload35
    68         File file = new File(dir);
    69         if(!file.exists()){
    70             //创建目录
    71             file.mkdirs();
    72         }
    73         return dir;
    74     }
    75     
    76     public void doPost(HttpServletRequest request, HttpServletResponse response)
    77             throws ServletException, IOException {
    78         doGet(request, response);
    79     }
    80 }
    DownLoadServlet  得到下载目录的servlet 

            

  • 相关阅读:
    Java 集合框架
    Java 网络编程
    Java序列化
    Java 发送邮件
    Java 多线程编程
    Java 文档注释
    Java Applet基础
    Python 基础教程
    Python 简介
    一步步学习SPD2010--第三章节--处理列表和库(19)----关键点
  • 原文地址:https://www.cnblogs.com/ou-pc/p/7894986.html
Copyright © 2011-2022 走看看