zoukankan      html  css  js  c++  java
  • 利用Servlet实现文件安全下载

    利用Servlet实现文件的下载功能,今天就利用上班时间做了一个小小的demo.在这里先说明一下:在实现Servlet下载的时候,大家可能会习惯性的在html页面直接写一个URL链接,如:

    http://127.0.0.1:7001/TestFileUpload/fileDownLoadServlet?filename=mm.txt&file_path=/day1/xiu.txt这是一种很不友好的方式,它容易暴露主机系统的文件路径,很不安全,别有用心的人如果知道了主机系统文件的目录结构,就很轻易的在浏览器的地址栏中输入这样的URL链接随意的下载系统文件。所以那种方式我就不建议采用了.

    首先写一个Servlet下载类,为了安全,我采用了post提交方式。

    public class FileDownLoadServlet extends HttpServlet{
    
    	private static final long serialVersionUID = 1L;
    	@Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
        		throws ServletException, IOException {
        	request.setCharacterEncoding("UTF-8");
        	response.setCharacterEncoding("UTF-8");
       	     //获得文件名
            String fileName=request.getParameter("filename");
             //获得文件所在的路径
            String filePath=request.getParameter("file_path");
            download(fileName,filePath,request,response);  	
        }
    
        public HttpServletResponse download(String fileName,String filePath,HttpServletRequest request, HttpServletResponse response) {
            try {
            	
            	request.setCharacterEncoding("UTF-8");
            	response.setCharacterEncoding("UTF-8");        	
            	ServletContext application=this.getServletContext();
               //application.getRealPath("/") 得到web应用的绝对路径
                File file = new File(application.getRealPath("/")+filePath);
              
                System.out.println("request path: "+application.getRealPath("/"));
                //返回URL请求的URL路径
                System.out.println("getContextPath :"+request.getContextPath());
                // 以流的形式下载文件。
                InputStream fis = new BufferedInputStream(new FileInputStream(file));
                byte[] buffer = new byte[fis.available()];
                fis.read(buffer);
                fis.close();
               // 清空response
                response.reset();
               // 设置response的Header         
                response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("utf-8"),"ISO-8859-1"));    
                response.addHeader("Content-Length", "" + file.length());
                response.setContentType("application/octet-stream");
                OutputStream out = new BufferedOutputStream(response.getOutputStream());
           
                out.write(buffer);   
                out.flush();
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            return response;
        }
    }
    

    之所以采用post提交方式,是因为get方式非常的不安全(虽然get()方式比较方便、直观)。

    之后就配置web.xnl文件,把Servlet配置进去.


    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" 
    	xmlns="http://java.sun.com/xml/ns/javaee" 
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
      
      <servlet>
            <servlet-name>attach</servlet-name>
            <servlet-class>com.future.zfs.util.FileDownLoadServlet</servlet-class>
        </servlet>
        
        <servlet-mapping>
            <servlet-name>attach</servlet-name>
            <url-pattern>/attach</url-pattern>
        </servlet-mapping>
    	
    
    </web-app>
    


     最后就写一个test.html文件啦.采用了URL链接方式提交表单,因为form表单自身的type="submit"方式在网页显示的是一个按钮,呵呵,本来下载应该是一个URL链接才是,个人想法。

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>test.html</title>
    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="this is my page">
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
        
        <script type="text/javascript">
           function download(){
        	   document.getElementById("form").submit();
           }
        </script>
      </head>
      <body>
          <form  id="form" action="attach"  method="post">
                <input type="hidden" name="filename" value="mm.txt" />
                <input type="hidden" name="file_path" value="/day1/xiu.txt"/>
          </form>           
          <a href="javascript:void(0)" onclick="download()">文件下载</a>
      </body>
    </html> 

     当你把鼠标移到文件下载这个链接上时,在浏览器的状态栏显示的时:javascript:void(0)  ,而不是文件的系统路径了。就算知道了文件路径在浏览器的地址输入地址也不会进行下载.。因为在地址栏的都是get()方式,而我们在下载类里写的是Post()方法。

    好了,一个安全下载的小demo就这样完成了.关于文件名的中文问题,我还没有找到解决办法,有知道的分享下呗.

    为了方便大家,我把我做的demo路径贴出来:

  • 相关阅读:
    缓存三大问题及解决方案
    布隆过滤器
    maven 详解
    Netty是什么?
    select、poll、epoll简介
    IO
    Java并发编程:Synchronized及其实现原理
    Java并发之AQS详解
    原子更新字段类
    AtomicStampedReference解决ABA问题
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300441.html
Copyright © 2011-2022 走看看