---恢复内容开始---

1. 使用HttpServletResponse对象实现文件下载

文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载。文件下载功能的实现思路:

  1.获取要下载的文件的绝对路径

  2.获取要下载的文件名

  3.设置content-disposition响应头控制浏览器以下载的形式打开文件

  4.获取要下载的文件输入流

  5.创建数据缓冲区

  6.通过response对象获取OutputStream流

  7.将FileInputStream流写入到buffer缓冲区

  8.使用OutputStream将缓冲区的数据输出到客户端浏览器

示例代码如下:

package myTest;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class FileDownload extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//下载文件,通过OutputStream流
downloadFileByOutputStream(response);
} private void downloadFileByOutputStream(HttpServletResponse response)
throws FileNotFoundException, IOException {
//1.获取要下载的文件的绝对路径
String realPath = this.getServletContext().getRealPath("/download/1.png");
//2.获取要下载的文件名
String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
//3.设置content-disposition响应头控制浏览器以下载的形式打开文件
response.setHeader("content-disposition", "attachment;filename="+fileName);
//4.获取要下载的文件输入流
InputStream in = new FileInputStream(realPath);
int len = 0;
//5.创建数据缓冲区
byte[] buffer = new byte[1024];
//6.通过response对象获取OutputStream流
OutputStream out = response.getOutputStream();
//7.将FileInputStream流写入到buffer缓冲区
while ((len = in.read(buffer)) > 0) {
//8.使用OutputStream将缓冲区的数据输出到客户端浏览器
out.write(buffer,0,len);
}
in.close();
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}

上述代码中:

1. getServletContext():返回对调用者正在执行的ServletContext的引用;

2. substring(int beginIndex):返回一个字符串,该字符串是此字符串的子字符串。 子串以指定索引处的字符开头,并延伸到此字符串的末尾。例如:"unhappy".substring(2) returns "happy","Harbison".substring(3) returns "bison","emptiness".substring(9) returns "" (an empty string);

编辑web.xml文件,运行后显示:

点击保存即可从服务器将该文件下载下来。

下载中文文件时,需要注意的地方就是中文文件名要使用URLEncoder.encode方法进行编码(URLEncoder.encode(fileName, "字符编码")),如下,否则会出现文件名乱码。

response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName,UTF-8));

编写文件下载功能时推荐使用OutputStream流,避免使用PrintWriter流,因为OutputStream流是字节流,可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失。

2. 生成验证码

生成随机图片用作验证码

生成图片主要用到了一个BufferedImage类。

示例代码如下:

package myTest;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class ImageDemo extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//设置refresh响应头控制浏览器每隔5秒钟刷新一次
response.setHeader("refresh", "5");
//1.在内存中创建一张图片
BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//2.得到图片
//Graphics g = image.getGraphics();
Graphics2D g = (Graphics2D)image.getGraphics();
g.setColor(Color.WHITE);//设置图片的背景色
g.fillRect(0, 0, 80, 20);//填充背景色
//3.向图片上写数据
g.setColor(Color.BLUE);//设置图片上字体的颜色
g.setFont(new Font(null, Font.BOLD, 20));
g.drawString(makeNum(), 0, 20);
//4.设置响应头控制浏览器浏览器以图片的方式打开
response.setContentType("image/jpeg");//等同于response.setHeader("Content-Type", "image/jpeg");
//5.设置响应头控制浏览器不缓存图片数据
response.setDateHeader("expries", -1);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
//6.将图片写给浏览器
ImageIO.write(image, "jpg", response.getOutputStream());
} /**
* 生成随机数字
* @return
*/
private String makeNum(){
Random random = new Random();
String num = random.nextInt(9999999)+"";
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 7-num.length(); i++) {
sb.append("0");
}
num = sb.toString()+num;
return num;
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }

配置xml.web文件,运行后显示结果:

因为设置了每5秒刷新一次,response.setHeader("refresh", "5"); 所以每隔5秒钟随机生成一个验证码。

3. 设置响应头控制浏览器的行为

3.1 设置http响应头控制浏览器禁止缓存当前文档内容

response.setDateHeader("expries", -1);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");

3.2 设置http响应头控制浏览器定时刷新网页(refresh)

//设置refresh响应头控制浏览器每隔5秒钟刷新一次
response.setHeader("refresh", "5");

3.3 通过response实现请求重定向

一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。比如配合302状态实现重定向。

response.setStatue(302);
response.setHeader(“location”,”/day06/index.jsp”)

或者sendRedirect(String location)实现重定向。

response.sendRedirect(“/day06/index.jsp”);

请求重定向会导致服务器接受两次请求,加重服务器的负担。所以一般不推荐使用(一般推荐转发方式)。但是在制作登录后跳转到首页这一功能的时候必须使用请求重定向,这可以使地址栏发生变化,主要是起到提示用户已跳转到首页的作用。还有购物的时候点击购物按钮跳转到购物车显示页面的时候需要使用请求重定向,它可以避免转发时点击刷新造成的多次够买的错误。

示例代码如下:

package myTest;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class sendRedirectDemo extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.sendRedirect("/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}

sendRedirect内部的实现原理是使用response设置302状态码和设置location响应头实现重定向,sendRedirect方法内部调用了以下两个方法

response.setHeader("Location", "/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
response.setStatus(HttpServletResponse.SC_FOUND);//设置302状态码,等同于response.setStatus(302);

4. web工程中URL地址的推荐写法

在JavaWeb开发中,只要是写URL地址,那么建议最好以"/"开头,也就是使用绝对路径的方式,如果"/"是给服务器用的,则代表当前的web工程,如果"/"是给浏览器用的,则代表webapps目录。

4.1 "/"代表当前web工程的常见应用场景

①.ServletContext.getRealPath(String path)获取资源的绝对路径

this.getServletContext().getRealPath("/download/1.JPG");//表示的就是读取web工程下的download文件夹中的1.JPG这个资源

②.在服务器端forward到其他页面

客户端请求某个web资源,服务器跳转到另外一个web资源,这个forward也是给服务器用的,那么这个"/"就是给服务器用的,所以此时"/"代表的就是web工程。

this.getServletContext().getRequestDispatcher("/index.jsp").forward(request, response);

③.使用include指令或者<jsp:include>标签引入页面

<%@include file="/jspfragments/head.jspf" %>
<jsp:include page="/jspfragments/demo.jsp" />

4.2 "/"代表webapps目录的常见应用场景

①.使用sendRedirect实现请求重定向

response.sendRedirect("/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");

服务器发送一个URL地址给浏览器,浏览器拿到URL地址之后,再去请求服务器,所以这个"/"是给浏览器使用的,此时"/"代表的就是webapps目录,"/JavaWeb_HttpServletResponse_Study_20140615/index.jsp"这个地址指的就是"webapps\JavaWeb_HttpServletResponse_Study_20140615\index.jsp"

response.sendRedirect("/项目名称/文件夹目录/页面");这种写法是将项目名称写死在程序中的做法,不灵活,万一哪天项目名称变了,此时就得改程序,所以推荐使用下面的灵活写法:

将上面这种写法改成:

response.sendRedirect(request.getContextPath()+"/index.jsp");

request.getContextPath()获取到的内容就是"/JavaWeb_HttpServletResponse_Study_20140615",这样就比较灵活了,使用request.getContextPath()代替"/项目名称",推荐使用这种方式,灵活方便!

②.使用超链接跳转

<a href="/JavaWeb_HttpServletResponse_Study_20140615/index.jsp">跳转到首页</a>

这是客户端浏览器使用的超链接跳转,这个"/"是给浏览器使用的,此时"/"代表的就是webapps目录。

使用超链接访问web资源,绝对路径的写法推荐使用下面的写法改进:

<a href="${pageContext.request.contextPath}/index.jsp">跳转到首页</a>

这样就可以避免在路径中出现项目的名称,使用${pageContext.request.contextPath}取代"/JavaWeb_HttpServletResponse_Study_20140615"

.Form表单提交

<form action="/JavaWeb_HttpServletResponse_Study_20140615/servlet/CheckServlet" method="post">
<input type="submit" value="提交">
</form>

这是客户端浏览器将form表单提交到服务器,所以这个"/"是给浏览器使用的,此时"/"代表的就是webapps目录。

对于form表单提交中action属性绝对路径的写法,也推荐使用如下的方式改进:

<form action="${pageContext.request.contextPath}/servlet/CheckServlet" method="post">
<input type="submit" value="提交">
</form>

${pageContext.request.contextPath}得到的就是"/JavaWeb_HttpServletResponse_Study_20140615",${pageContext.request.contextPath}的效果等同于request.getContextPath(),两者获取到的都是"/项目名称"。

④.js脚本和css样式文件的引用

 <%--使用绝对路径的方式引用js脚本--%>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/index.js"></script>
<%--${pageContext.request.contextPath}与request.getContextPath()写法是得到的效果是一样的--%>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/login.js"></script>
<%--使用绝对路径的方式引用css样式--%>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/index.css" type="text/css"/>

wx搜索“程序员考拉”,专注java领域,一个伴你成长的公众号!

HttpServletResponse对象(二)之常见应用的更多相关文章

  1. java web学习总结(八) -------------------HttpServletResponse对象(二)

    一.HttpServletResponse常见应用--生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类,

  2. JavaWeb---总结(八)HttpServletResponse对象(二)

    一.HttpServletResponse常见应用--生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类, 生成随机图片范例: 1 package gacl ...

  3. javaweb学习总结(八)——HttpServletResponse对象(二)

    一.HttpServletResponse常见应用——生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类,

  4. JavaWeb学习 (八)————HttpServletResponse对象(二)

    一.HttpServletResponse常见应用——生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类,

  5. HttpServletResponse对象(二)

    一.HttpServletResponse常见应用——生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类,

  6. javaweb(八)——HttpServletResponse对象(二)

    一.HttpServletResponse常见应用——生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类, 生成随机图片范例: 1 package gacl ...

  7. avaweb学习总结(八)——HttpServletResponse对象(二)

    一.HttpServletResponse常见应用——生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类,

  8. javaweb学习总结(八)——HttpServletResponse对象(二)(转)

    (每天都会更新至少一篇以上,有兴趣的可以关注)转载自孤傲苍狼 一.HttpServletResponse常见应用——生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedI ...

  9. JavaWeb总结(二)—HttpServletResponse对象

    Web服务器收到客户端的http请求,会针对每一次的请求,分别创建一个用于代表请求的request对象和response对象.我们要获取客户端提交的数据,只需要找request对象.要向客户端输出数据 ...

随机推荐

  1. JQuery实现全选、反选和取消功能

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. Linux 下四条高大命令(计划360检测脚本)

    查看进程,按内存从大到小 ps -e -o "%C : %p : %z : %a"|sort -k5 -nr 查看进程,按CPU利用率从大到小排序 ps -e -o "% ...

  3. ArchLinux 下 virtualbox 报错 libQtCore.so.4: cannot open shared object file

    VirtualBox: supR3HardenedMainGetTrustedMain: dlopen("/usr/lib/virtualbox/VirtualBox.so",) ...

  4. ArchLinux 下 OpenSSH 高级运用

    00x0.相关介绍 OpenSSH(OpenBSD Secure Shell)使用 SSH 通过计算机网络加密通信的实现. 它是替换由 SSH Communications Security 所提供的 ...

  5. PyQt5(5)——加载资源文件

    在实际中我们需要美化界面,就需要许多的自定义图片. 但是我们发现直接导入图像使用,等程序运行时会报错.???? 这就需要建立资源文件并且加载它们,程序就可以顺利运行了. 设计界面是如何加载资源文件呢? ...

  6. iOS tableview性能优化及分析

    1.最常用的就是cell的重用, 注册重用标识符 每次滑动cell时需要先去缓存池中寻找可循环利用的cell,如果没有则再重新创建cell 2.减少cell中控件的数量 view对象尽量缩减控件的数量 ...

  7. Linux系统查找清理磁盘大文件方法

    本文主要介绍Linux系统磁盘使用空间不足时,如何查找大文件并进行清理的方法. 下午使用df-h检查一台服务器磁盘使用空间,发现磁盘已经使用了100%,其中/dev/mapper/vg_iavp-lv ...

  8. 函数新特性、内联函数、const详解

    一.函数回顾与后置返回类型 函数定义中,形参如果在函数体内用不到的话,则可以不给形参变量名字,只给其类型. 函数声明时,可以只有形参类型,没有形参名 把函数返回类型放到函数名字之前,这种写法,叫前置返 ...

  9. [inside hotspot] 汇编模板解释器(Template Interpreter)和字节码执行

    [inside hotspot] 汇编模板解释器(Template Interpreter)和字节码执行 1.模板解释器 hotspot解释器模块(hotspot\src\share\vm\inter ...

  10. Windows下的特殊unicode输入

    相信很多运维人员见过这样的一种输入方法,按住键盘的ALT键然后在小键盘处输入88,放开ALT键,然后再按住ALT在小键盘处输入80,再放开键盘,屏幕光标文本处就会依次出现XP这个2个字母,这个很神奇, ...