一、文件下载概述

比如图片或者HTML这类静态资源,仅仅要在浏览器中打开正确的网址就行下载。仅仅要资源放在应用程序文件夹或者其下的子文件夹中,但不在WEB-INF下。Servlet/JSP容器就会将资源发送到浏览器。

但有的时候,静态资源被保存在应用程序文件夹之外,或者保存在数据库中。或者有时候你须要控制让某些人可以看到这个资源,同一时候又要防止其它站点引用它。每当遇到这类情况时,就必须通过编程来发送资源。

通过编程的方式实现文件下载但是让我们有选择的将一个文件发送到浏览器。

为了将资源比方文件发送到浏览器,须要在Servlet中完毕下面工作。这里说明下面。一般不用JSP页面。由于要发送的是浏览器不会显示的二进制代码。

1.将响应内容类型设置为“文件”的内容类型。

标头Content-Type用来规定实体主体中的数据类型,包括“媒体类型”和“子类型标示符”。假设希望浏览器总是显示为“Save as”对话框时,就将内容类型设置为:application/octetstream。

2.加入一个名为content-disposition的HTTP响应标头。

给上述响应标头赋值:attachment;filename="XXX"。这里的XXX是在文件下载对话框中显示的默认文件名称。

他能够与真实的文件名称同样,也能够不同。

以下是一个文件下载的实例概述:

response.setContentType(contenttype);
FileInputStream fis=new FileInputStream(file);
BufferedInputStream bis=new BufferedInputStream(fis);
byte[] bytes=new byte[1024];
OutputStream os=response.getOutputStream();
bis.read(bytes);
os.write(bytes);

首先,将要下载的文件当成一个FileInputStream,并将内容加入到一个字节数组中。

然后获取HttpServletResponse的OutputStream。并调用它的write()方法。将字节数组传递给它。

二、下载隐藏文件实例

在以下这个演示样例中,secret.pdf文件放在WEB-INF/data里。不同意直接訪问。用一个FileDownloadServlet将secret.pdf文件发送到浏览器,可是授权用户才干浏览。假设用户没有登录。应用程序就会跳转到login界面,这里,用户能够在表单中输入username和password,这些内容都被提交到还有一个LoginServlet处理。

以下是该应用程序的结构图:

1.用户提交登录表单

login.jsp页面,包括一个HTML表单,当中有两个输入域:userName和password

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>Login</title>
</head>
<body>
<form action="login" method="post">
<table>
<tr>
<td>User Name:</td>
<td><input type="text" name="userName"/></td>
</tr>
<tr>
<td>PassWord:</td>
<td><input type="password" name="password"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="login"/></td>
</tr>
</table>
</form>
</body>
</html>

提交表单时会调用LoginServlet。它的类代码例如以下。

在这个应用程序中,我如果username与password必须是ken/secret。

package filedownload;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; /**
* Servlet implementation class LoginServlet
*/
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public LoginServlet() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String username=request.getParameter("userName");
String password=request.getParameter("password");
if(username!=null&&username.equals("ken")&&password!=null&&password.equals("secret")){
HttpSession session=request.getSession(true);
session.setAttribute("loggedIn", Boolean.TRUE);
response.sendRedirect("download");
//must call return or else the code after this if
//block,if any,will be executed
 return;
}else{
RequestDispatcher dispatcher=request.getRequestDispatcher("/login.jsp");
dispatcher.forward(request, response);
}
} }<span style="font-size:14px;">
</span>

用户登录成功后,会设置一个loggedln会话属性,并将用户转到FileDownloadServlet。

在HttpServletResponse.sendRedirect之后。必须返回,以防止运行后面的代码行。登录失败后,则会将用户转到login.jsp页面。

2.进行文件下载

FileDownloadServlet展示了一个负责发送secret.pdf文件的Servlet。仅仅有当用户的HttpSession中包括loggedlin属性时,表示用户已经成功登录,此时才同意訪问。

package filedownload;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream; import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; /**
* Servlet implementation class FileDownloadServlet
*/
public class FileDownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public FileDownloadServlet() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
HttpSession session=request.getSession();
if(session==null||session.getAttribute("loggedIn")==null){
RequestDispatcher dispatcher=request.getRequestDispatcher("/login.jsp");
dispatcher.forward(request, response);
return;//must return after dispatcher.forward(),Otherwise the code below will be executed
}
String dataDirectory =request.getServletContext().getRealPath("/WEB-INF/data/secret.pdf");
//System.out.println(dataDirectory);
File file=new File(dataDirectory);
if(file.exists()){
response.setContentType("application/pdf");
response.addHeader("Content-Disposition", "attachment;filename=secret.pdf");
byte[] buffer=new byte[1024];
FileInputStream fis=null;
BufferedInputStream bis=null;
try{
fis=new FileInputStream(file);
bis=new BufferedInputStream(fis);
OutputStream os=response.getOutputStream();
int i=bis.read(buffer);
while(i!=-1){
os.write(buffer,0,i);
i=bis.read(buffer);
}
}catch(IOException e){
System.out.println(e.toString());
}finally{
if(bis!=null){
bis.close();
}
if(fis!=null){
fis.close();
}
}
}else{
System.out.println("secret.pdf does not exit!");
}
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
} }

doGet方法会检查HttpSession中是否有loggedIn属性。

假设没有,则会将用户带到登录界面。

HttpSession session=request.getSession();
if(session==null||session.getAttribute("loggedIn")==null){
RequestDispatcher dispatcher=request.getRequestDispatcher("/login.jsp");
dispatcher.forward(request, response);
return;//must return after dispatcher.forward(),Otherwise the code below will be executed
}

注意。在RequestDispatcher中调用forward会将控制权转移到不同的资源。可是,它不会中止当前在调用对象的代码运行,因此。跳转之后必须返回。

假设用户已经登录成功。doGet方法就会打开索要的资源,并将它引到ServletResponse的OutputStream。

String dataDirectory =request.getServletContext().getRealPath("/WEB-INF/data/secret.pdf");
//System.out.println(dataDirectory);
File file=new File(dataDirectory);
if(file.exists()){
response.setContentType("application/pdf");
response.addHeader("Content-Disposition", "attachment;filename=secret.pdf");
byte[] buffer=new byte[1024];
FileInputStream fis=null;
BufferedInputStream bis=null;
try{
fis=new FileInputStream(file);
bis=new BufferedInputStream(fis);
OutputStream os=response.getOutputStream();
int i=bis.read(buffer);
while(i!=-1){
os.write(buffer,0,i);
i=bis.read(buffer);
}
}catch(IOException e){
System.out.println(e.toString());
}finally{
if(bis!=null){
bis.close();
}
if(fis!=null){
fis.close();
}
}
}else{
System.out.println("secret.pdf does not exit!");
}

利用以下的URL调用FileDownloadServlet,能够对该应用程序进行測试:

http://localhost:8080/app12a/download

3.PS:web.xml配置文件

<?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_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>app12a</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>FileDownloadServlet</display-name>
<servlet-name>FileDownloadServlet</servlet-name>
<servlet-class>filedownload.FileDownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileDownloadServlet</servlet-name>
<url-pattern>/download</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>LoginServlet</display-name>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>filedownload.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>

4.測试截图

摘录自:《Servlet和JSP学习指南》

Servlet学习笔记(八)—— 文件下载的更多相关文章

  1. python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑

    python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件?当我们点开下载页时, 一般 ...

  2. Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  3. Go语言学习笔记八: 数组

    Go语言学习笔记八: 数组 数组地球人都知道.所以只说说Go语言的特殊(奇葩)写法. 我一直在想一个人参与了两种语言的设计,但是最后两种语言的语法差异这么大.这是自己否定自己么,为什么不与之前统一一下 ...

  4. 【opencv学习笔记八】创建TrackBar轨迹条

    createTrackbar这个函数我们以后会经常用到,它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上,使用起来很方便.首先大家要记住,它往往会和一个回调函数配合起来使用.先看下他的函数 ...

  5. # jsp及servlet学习笔记

    目录 jsp及servlet学习笔记 JSP(Java Server Page Java服务端网页) 指令和动作: servlet(小服务程序) jsp及servlet学习笔记 JSP(Java Se ...

  6. go微服务框架kratos学习笔记八 (kratos的依赖注入)

    目录 go微服务框架kratos学习笔记八(kratos的依赖注入) 什么是依赖注入 google wire kratos中的wire Providers injector(注入器) Binding ...

  7. Servlet学习笔记(四)

    目录 Servlet学习笔记(四) 一.会话技术Cookie.session 1. 什么是会话技术? 2. 会话技术有什么用? 3. Cookie 3.1 什么是Cookie? 3.2 使用Cooki ...

  8. Servlet学习笔记(三)

    目录 Servlet学习笔记(三) 一.HTTP协议 1.请求:客户端发送欸服务器端的数据 2.响应:服务器端发送给客户端的数据 3.响应状态码 二.Response对象 1.Response设置响应 ...

  9. Servlet学习笔记(二)

    目录 Servlet学习笔记(二) Request对象 1.request和response对象: 2.request对象继承体系结构: 3.什么是HttpServletRequest ? 4.Htt ...

  10. Redis学习笔记八:集群模式

    作者:Grey 原文地址:Redis学习笔记八:集群模式 前面提到的Redis学习笔记七:主从复制和哨兵只能解决Redis的单点压力大和单点故障问题,接下来要讲的Redis Cluster模式,主要是 ...

随机推荐

  1. struts2 使用json

    前台代码: Struts.xml: UserAction: 注意: 1)struts类库里面没有提供ezmorph-1.0.6.jar文件,所以要手动添加:

  2. 04Hibernate连接数据库环境配置

    Hibernate连接数据库环境配置

  3. 09Windows编程

    Windows编程 2.1      窗口 Windows应用程序一般都有一个窗口,窗口是运行程序与外界交换信息的界面.一个典型的窗口包括标题栏.最小化按钮.最大/还原按钮.关闭按钮.系统菜单图标.菜 ...

  4. 记录一次通过命令行方式来使用svn碰到的一系列问题

    由于使用Xcode自带的svn管理碰到很多问题,搞得头昏脑胀,找资料时看到小码哥这方面的视频,看完就开始折腾了. 准备:1.远程仓库地址及授权账号(用户名和密码) 2.一份项目代码,之所以要有这份代码 ...

  5. oracle分配权限 学习笔记--转载

    在全局数据库ORCL下创建一个用户首先在开始-->运行——>sqlplus,然后输入 sys/change_on_install as sysdba 以sys权限登陆进去 然后可以进行操作 ...

  6. show()的几种方法

    1 show()方法和hide()方法 $("selector").show()  从display:none还原元素默认或已设置的display属性$("selecto ...

  7. 源码学习-Object类

    1.Object类是Java所有类的超类 2.查看Object的属性和方法,发现Object类没有属性,只有13个方法,其中7个本地方法. 3.接下来看具体的方法 3.1 Object() 默认的构造 ...

  8. windows 安装 python3

    安装python------------------------------------------------------------ 1,打开连接https://www.python.org/do ...

  9. linux虚拟环境搭建

    一.virtualenv的安装与使用 1.安装virtualenv pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple virtualen ...

  10. CUDA_one

    首先我看了讲解CUDA基础部分以后,大致对CUDA的基本了解如下: 第一:CUDA实行并行化的过程分为两部分,一个是线程块之间的并行(这是在每个线程网格中grid进行的),一个是对于每一个线程块内部各 ...