第十一章_文件下载

简介:

11.1、文件下载概述

1、将响应的内容类型设置为文件的内容类型。标头Content-type用来规定实体主体中的数据类型,包含媒体类型和子类型标识符。

2、添加一个名为Content-DispositionHTTP响应头,给它赋值attachmentfilename=filename,这里的fileName是指在文件下载对话框中显示出来的默认文件名。它通常与文件名相同,但是也可以不同。

例如,以下就是将一个文件发送到浏览器的代码范例。

FileInputStream fis = new FileInputStream(file) ;

BufferedInputStream bis = new BufferedInputStream(fis) ;

byte[] bytes = new byte[bis.available()] ;

response.setContentType(contentType) ;

OutputStream os = response.getOutputStream() ;

bis.read(bytes) ;

os.write(bytes) ;

警告:一定要确保你没有在无意中发送超出实际文件内容以外的任何字符。这有可能在你毫不知情的情况下发生。例如,如果需要在JSP页面中使用page指令,可以这么写:

<%@ page import=”Java.io.FileInputStream”%>

<jsp:useBean id=”DBBeanId” scope=”page” class=”MyBean”>

在你毫不察觉的情况下,page指令后面的回车换行符就会被发送给浏览器。为了防止发送多余的字符,需要像下面这样编写这个指令:

<%@ page import=”java.io.FileInputStream”

%><jsp:useBean id=”DBBeanId” scope=”page” class=”MyBean”>

 

11.2、范例1:隐藏资源

在下面这个程序中,我们用一个FileDownloadServlet servletsecret.pdf文件发送到浏览器。但是,只有授权用户才能浏览。如果用户没有登录,应用程序就会跳转到Login页面。在这里,用户可以在表单中输入用户名和密码,这些内容都将被提交给另一个ServletLoginServlet

LoginServlet.java

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. package filedownloaded;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.RequestDispatcher;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.annotation.WebServlet;  
  8. import javax.servlet.http.HttpServlet;  
  9. import javax.servlet.http.HttpServletRequest;  
  10. import javax.servlet.http.HttpServletResponse;  
  11. import javax.servlet.http.HttpSession;  
  12. @WebServlet(urlPatterns = {"/login"})  
  13. public class LoginServlet extends HttpServlet{  
  14.   
  15.     private static final long serialVersionUID = 1L;  
  16.       
  17.     public void doPost(HttpServletRequest request,  
  18.             HttpServletResponse response) throws ServletException,  
  19.             IOException {  
  20.         String userName = request.getParameter("userName") ;  
  21.         String password = request.getParameter("password") ;  
  22.         if(userName != null && userName.equals("ken")  
  23.                 && password != null && password.equals("secret")){  
  24.             HttpSession session = request.getSession(true) ;  
  25.             session.setAttribute("loggedIn", Boolean.TRUE);  
  26.             response.sendRedirect("download");  
  27.             return ;  
  28.         }else{  
  29.             RequestDispatcher dispatcher =   
  30.                     request.getRequestDispatcher("/login.jsp") ;  
  31.             dispatcher.forward(request, response);  
  32.         }  
  33.     }  
  34.       
  35. }  

login.jsp
[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6.   
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  8. <html>  
  9.   <head>  
  10.     <base href="<%=basePath%>">  
  11.       
  12.     <title>My JSP 'login.jsp' starting page</title>  
  13.       
  14.     <meta http-equiv="pragma" content="no-cache">  
  15.     <meta http-equiv="cache-control" content="no-cache">  
  16.     <meta http-equiv="expires" content="0">      
  17.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  18.     <meta http-equiv="description" content="This is my page">  
  19.     <!-- 
  20.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  21.     -->  
  22.   
  23.   </head>  
  24.     
  25.   <body>  
  26.     <form action="login" method="post">  
  27.         <table>  
  28.             <tr>  
  29.                 <td>User name: </td>  
  30.                 <td><input name="userName"/></td>  
  31.             </tr>  
  32.             <tr>  
  33.                 <td>Password: </td>  
  34.                 <td><input name="password" type="password"/></td>  
  35.             </tr>  
  36.             <tr>  
  37.                 <td colspan="2">  
  38.                     <input type="submit" value="login"/>  
  39.                 </td>  
  40.             </tr>  
  41.         </table>  
  42.     </form>  
  43.   </body>  
  44. </html>  
FileDownloadServlet.java

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. package filedownloaded;  
  2.   
  3. import java.io.BufferedInputStream;  
  4. import java.io.File;  
  5. import java.io.FileInputStream;  
  6. import java.io.IOException;  
  7. import java.io.OutputStream;  
  8.   
  9. import javax.servlet.RequestDispatcher;  
  10. import javax.servlet.ServletException;  
  11. import javax.servlet.annotation.WebServlet;  
  12. import javax.servlet.http.HttpServlet;  
  13. import javax.servlet.http.HttpServletRequest;  
  14. import javax.servlet.http.HttpServletResponse;  
  15. import javax.servlet.http.HttpSession;  
  16. @WebServlet(urlPatterns = {"/download"})  
  17. public class FileDownloadServlet extends HttpServlet{  
  18.   
  19.     private static final long serialVersionUID = 1L;  
  20.       
  21.     @Override  
  22.     public void doGet(HttpServletRequest req, HttpServletResponse resp)  
  23.             throws ServletException, IOException {  
  24.         HttpSession session = req.getSession() ;  
  25.         if(session == null || session.getAttribute("loggedIn") == null){  
  26.             RequestDispatcher dispatcher = req.getRequestDispatcher("/login.jsp") ;  
  27.             dispatcher.forward(req, resp);   
  28.             return ;  
  29.         }  
  30.         String dataDirectory = req.getServletContext().getRealPath("/WEB-INF/data") ;  
  31.         File file = new File(dataDirectory, "secret.pdf") ;  
  32.         if(file.exists()){  
  33.             resp.setContentType("application/pdf");  
  34.             resp.addHeader("Content-Disposition", "attachment; filename=secret.pdf");  
  35.             byte[] buffer = new byte[1024] ;  
  36.             try(FileInputStream fis = new FileInputStream(file) ;  
  37.                 BufferedInputStream bis = new BufferedInputStream(fis);  
  38.                 OutputStream os = resp.getOutputStream()){  
  39.                 int i = bis.read(buffer) ;  
  40.                 while(i != -1){  
  41.                     os.write(buffer, 0, i);  
  42.                     i = bis.read(buffer) ;  
  43.                 }  
  44.             }catch(IOException e){  
  45.                 e.printStackTrace();  
  46.             }  
  47.         }  
  48.     }  
  49.       
  50. }  

12.3、范例2:防止跨站引用

竞争对手很可能试图通过跨站引用来“窃取”你的网络资产,例如将你的贵重物品显示在他们的网站上,好像哪些东西就是他们的一样,如果通过编程的方式,仅当referer标头中包含你的域名时才发送资源,那么就可以防止上述情况的发生。当然,那种意志坚定的窃贼还是有可能下载到你的资产,但是那就要费一番功夫了。

下面的应用使用了一个Servlet,当且仅当referer标头不为空时,才将图片发送到浏览器。这样就可以防止直接在浏览器中输入其网址就能下载到图片。

ImageServlet.java

[html]  view plain  copy
 print ?
  1. package filedownloaded;  
  2.   
  3. import java.io.BufferedInputStream;  
  4. import java.io.File;  
  5. import java.io.FileInputStream;  
  6. import java.io.IOException;  
  7. import java.io.OutputStream;  
  8.   
  9. import javax.servlet.ServletException;  
  10. import javax.servlet.annotation.WebServlet;  
  11. import javax.servlet.http.HttpServlet;  
  12. import javax.servlet.http.HttpServletRequest;  
  13. import javax.servlet.http.HttpServletResponse;  
  14. @WebServlet(urlPatterns = {"/getImage"})  
  15. public class ImageServlet extends HttpServlet{  
  16.   
  17.     private static final long serialVersionUID = 1L;  
  18.       
  19.     public void doGet(HttpServletRequest request,   
  20.             HttpServletResponse response) throws ServletException,  
  21.             IOException{  
  22.         String referer = request.getHeader("referer") ;  
  23.         if(referer != null){  
  24.             String imageId = request.getParameter("id") ;  
  25.             String imageDirectory = request.getServletContext().getRealPath("/WEB-INF/image") ;  
  26.             File file = new File(imageDirectory, imageId + ".jpg") ;  
  27.             if(file.exists()){  
  28.                 response.setContentType("image/jpg");  
  29.                 byte[] buffer = new byte[1024] ;  
  30.                 try(FileInputStream fis = new FileInputStream(file) ;  
  31.                     BufferedInputStream bis = new BufferedInputStream(fis);  
  32.                     OutputStream os = response.getOutputStream()){  
  33.                     int i = bis.read(buffer) ;  
  34.                     while(i != -1){  
  35.                         os.write(buffer, 0, i);  
  36.                         i = bis.read(buffer) ;  
  37.                     }  
  38.                 }catch(IOException e){  
  39.                     e.printStackTrace();  
  40.                 }  
  41.             }  
  42.         }  
  43.     }  
  44.       
  45. }  

images.html

[html]  view plain  copy
 print ?
  1. <!DOCTYPE html>  
  2. <html>  
  3.   <head>  
  4.     <title>images.html</title>  
  5.       
  6.     <meta name="keywords" content="keyword1,keyword2,keyword3">  
  7.     <meta name="description" content="this is my page">  
  8.     <meta name="content-type" content="text/html; charset=UTF-8">  
  9.       
  10.     <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->  
  11.   
  12.   </head>  
  13.     
  14.   <body>  
  15.     <img src="getImage?id=1"/>  
  16.     <img src="getImage?id=2"/>  
  17.     <img src="getImage?id=3"/>  
  18.     <img src="getImage?id=4"/>  
  19.     <img src="getImage?id=5"/>  
  20.     <img src="getImage?id=6"/>  
  21.     <img src="getImage?id=7"/>  
  22.     <img src="getImage?id=8"/>  
  23.     <img src="getImage?id=9"/>  
  24.     <img src="getImage?id=10"/>  
  25.   </body>  
  26. </html>  

这样就能避免其他网站使用爬虫等技术进行图片下载。直接复制图片地址是访问不到图片的。
目录
相关文章
|
安全 开发工具 git
CTF工具隐写分离神器Binwalk安装和详细使用方法
CTF工具隐写分离神器Binwalk安装和详细使用方法
1586 0
|
1月前
|
JavaScript 前端开发 编译器
吐血整理:纯前端如何实现批量dom转图片,并下载成压缩包
【10月更文挑战第2天】吐血整理:纯前端如何实现批量dom转图片,并下载成压缩包
56 2
|
1月前
|
存储 前端开发 Java
Java后端如何进行文件上传和下载 —— 本地版(文末配绝对能用的源码,超详细,超好用,一看就懂,博主在线解答) 文件如何预览和下载?(超简单教程)
本文详细介绍了在Java后端进行文件上传和下载的实现方法,包括文件上传保存到本地的完整流程、文件下载的代码实现,以及如何处理文件预览、下载大小限制和运行失败的问题,并提供了完整的代码示例。
525 1
视频文件上传接口上传不了,怎样解决??
视频文件上传接口上传不了,怎样解决??
|
6月前
|
Python
用Python实现批量下载文件
用Python实现批量下载文件
|
6月前
【绝对贴心的代码】把网址生成二维码并且下载为图片文件,送到你嘴里的源码,关注点个赞呗!
【绝对贴心的代码】把网址生成二维码并且下载为图片文件,送到你嘴里的源码,关注点个赞呗!
|
前端开发
前端常规关于网页文件下载的问题
前端常规关于网页文件下载的问题
63 0
|
6月前
教会你怎么玩转 文件下载
教会你怎么玩转 文件下载
52 0
|
6月前
|
JSON 前端开发 JavaScript
前端上传文件前检测文件数据🔍
前端上传文件前检测文件数据🔍
127 0
|
编解码 JavaScript 前端开发
Web阶段:第十五章:文件上传&下载
Web阶段:第十五章:文件上传&下载
113 0
Web阶段:第十五章:文件上传&下载