一、response概述

  response是Servlet.service方法的一个参数,类型为javax.servlet.http.HttpServletResponse。在客户端发出每个请求时,服务器都会创建一个response对象,并传入给Servlet.service()方法。response对象是用来对客户端进行响应的,这说明在service()方法中使用response对象可以完成对客户端的响应工作

二、response的运行流程

三、response的功能

  通过抓包工具抓取Http响应

  

  因为response代表响应,所以我们可以通过该对象分别设置Http响应的响应行,响应头和响应体。

3.1 设置响应行

  setStatus(int sc)

  • 200表示成功
  • 302表示重定向
  • 404表示客户端错(访问的资源不存在)
  • 500表示服务器端错

3.2 设置响应头

  可以使用response对象的setHeader()方法来设置响应头!使用该方法设置的响应头最终会发送给客户端浏览器!

  • response.setHeader(“content-type”, “text/html;charset=utf-8”):设置content-type响应头,该头的作用是告诉浏览器响应内容为html类型,编码为utf-8。而且同时会设置response的字符流编码为utf-8,即response.setCharaceterEncoding(“utf-8”);

  • response.setHeader("Refresh","5; URL=http://www.baidu.cn"):5秒后自动跳转到百度主页。

    禁用浏览器缓存:
    response.setHeader("Cache-Control", "no-cache");
    response.setHeader("pragma", "no-cache");
    response.setDateHeader("expires", -1);

3.3 设置响应体

【两个流】

  response是响应对象,向客户端输出响应正文(响应体)可以使用response的响应流,repsonse一共提供了两个响应流对象:

  • PrintWriter out = response.getWriter():获取字符流;
  • ServletOutputStream out = response.getOutputStream():获取字节流;

  当然,如果响应正文内容为字符,那么使用response.getWriter(),如果响应内容是字节,例如下载时,那么可以使用response.getOutputStream()。

  注意,在一个请求中,不能同时使用这两个流!也就是说,要么你使用repsonse.getWriter(),要么使用response.getOutputStream(),但不能同时使用这两个流。不然会抛出IllegalStateException异常。

【解决中文乱码问题】

  

  在使用response.getWriter()时需要注意默认字符编码为ISO-8859-1,如果希望设置字符流的字符编码为utf-8,可以使用response.setCharaceterEncoding(“utf-8”)来设置。这样可以保证输出给客户端的字符都是使用UTF-8编码的!

  但客户端浏览器并不知道响应数据是什么编码的!如果希望通知客户端使用UTF-8来解读响应数据,那么还是使用response.setContentType("text/html;charset=utf-8")方法比较好,因为这个方法不只会调用response.setCharaceterEncoding(“utf-8”),还会设置content-type响应头,客户端浏览器会使用content-type头来解读响应数据。

  注意:response.setContentType("text/html;charset=UTF-8")必须在getWriter()方法之前调用!

3.4 重定向

  

  重定向是服务器通知浏览器去访问另一个地址,即再发出另一个请求。

【重定向的实现方式】

/**
* 重定向:
* 1.设置Location
* 2.发送302状态码
*/
// response.setHeader("Location", "/day01/CServlet");
// 快捷的重定向方法
response.sendRedirect("/day01/CServlet");

【重定向的特点】

  • 重定向是两次请求(访问服务器两次或多次);
  • 重定向的URL可以是其他应用,不局限于当前应用;
  • 地址栏的地址发生变化
  • 重定向的响应头为302,并且必须要有Location响应头;

  注意:重定向就不要再使用response.getWriter()或response.getOutputStream()输出数据,不然可能会出现异常;

四、文件下载

  下载就是向客户端响应字节数据。原来我们响应的都是html的字符数据,下载就是把一个文件变成字节数组,使用response.getOutputStream()来各应给浏览器。

4.1 下载的要求

【两个头】

  • Content-Type:你传递给客户端的文件是什么MIME类型,例如:image/pjpeg(通过文件名称调用ServletContext的getMimeType()方法,得到MIME类型!)
  • Content-Disposition:它的默认值为inline,表示在浏览器窗口中打开!设置attachment;filename=xxx,表示浏览器弹出下载框,在filename=后面跟随的是显示在下载框中的文件名称!

【一个流】

  要下载的文件数据。FileInputStream input = new FileInputStream(filename)

4.2 下载实例

  download.jsp:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="/WEB14/download/a.jpg">a.jpg</a><br>
<a href="/WEB14/downLoadServlet2?filename=美女.jpg">美女.jpg</a><br>
</body>
</html>

  DownloadServlet:

public class DownloadServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 两个头、一个流
* 1.Content-Type
* 2.Content-Disposition
* 3.流:下载文件的数据
*/
// 获取要下载的文件名称
String filename = request.getParameter("filename"); // ??.jpg
// 为了使下载框中显示中文名称时不乱码
filename = new String(filename.getBytes("ISO8859-1"), "UTF-8"); //美女.jpg // 获取请求头中的User-Agent
String agent = request.getHeader("User-Agent");
String filenameEncoder = "";
if (agent.contains("MSIE")) {
// IE浏览器
filenameEncoder = URLEncoder.encode(filename, "utf-8");
filenameEncoder = filenameEncoder.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
filenameEncoder = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它浏览器
filenameEncoder = URLEncoder.encode(filename, "utf-8");
} // 要下载的这个文件的类型——客户端通过文件的MIME类型去区分类型
response.setContentType(this.getServletContext().getMimeType(filename));
// 告诉客户端该文件不是直接解析,而是以附件的形式打开(下载)
response.setHeader("Content-Disposition", "attachment;filename=" + filenameEncoder);
// 获取文件的绝对路径
String realPath = this.getServletContext().getRealPath("download/" + filename);
// 获取该文件的输入流
InputStream inputStream = new FileInputStream(realPath);
// 获得输出流——通过response获得的输出流,用于向客户端写内容
ServletOutputStream outputStream = response.getOutputStream();
// 文件拷贝的模板代码
int len = 0;
byte[] bytes = new byte[1024];
while ((len = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
} inputStream.close();
// outputStream.close(); response获得流不用手动关闭,会自动关闭
} public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}

JavaWeb学习笔记(四)—— response的更多相关文章

  1. JavaWeb学习笔记四 request&response

    HttpServletResponse 我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应res ...

  2. JavaWeb学习笔记总结 目录篇

    JavaWeb学习笔记一: XML解析 JavaWeb学习笔记二 Http协议和Tomcat服务器 JavaWeb学习笔记三 Servlet JavaWeb学习笔记四 request&resp ...

  3. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  4. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  5. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  6. Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices

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

  7. Typescript 学习笔记四:回忆ES5 中的类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  8. ES6学习笔记<四> default、rest、Multi-line Strings

    default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...

  9. muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制

    目录 muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制 eventfd的使用 eventfd系统函数 使用示例 EventLoop对eventfd的封装 工作时序 runInLoo ...

  10. python3.4学习笔记(四) 3.x和2.x的区别,持续更新

    python3.4学习笔记(四) 3.x和2.x的区别 在2.x中:print html,3.x中必须改成:print(html) import urllib2ImportError: No modu ...

随机推荐

  1. sql server2008 跨服务器之间复制表数据

    首先2个数据库要能互相访问,在本地数据库用 select * into 新表 from opendatasource('SQLOLEDB','Data Source=远程数据库IP;User ID=用 ...

  2. 使用GDB调试PHP代码,解决PHP代码死循环

    最近在帮同事解决Swoole Server问题时,发现有1个worker进程一直处于R的状态,而且CPU耗时非常高.初步断定是PHP代码中发生死循环. 下面通过一段代码展示如何解决PHP死循环问题. ...

  3. 分布式文件系统MFS(moosefs)实现存储共享

    分布式文件系统MFS(moosefs)实现存储共享(第二版) 作者:田逸(sery@163.com) 由于用户数量的不断攀升,我对访问量大的应用实现了可扩展.高可靠的集群部署(即lvs+keepali ...

  4. Codeforces 1120D (树形DP 或 最小生成树)

    题意看这篇博客:https://blog.csdn.net/dreaming__ldx/article/details/88418543 思路看这篇:https://blog.csdn.net/cor ...

  5. SQL Server CLR全功略之一---CLR介绍和配置

    Microsoft SQL Server 现在具备与 Microsoft Windows .NET Framework 的公共语言运行时 (CLR) 组件集成的功能.CLR 为托管代码提供服务,例如跨 ...

  6. Docker 学习笔记_安装和使用MongoDB

    一.准备 1.宿主机OS:Win10 64 2.虚拟机OS:Ubuntu18.04 3.账号:docker 二.安装 1.搜索MongoDB镜像                            ...

  7. 关于for循环的一个小问题

    有如下程序: package com.lk.B; public class Test5 { public static void main(String[] args) { // TODO Auto- ...

  8. poj 1611 The Suspects(第一道并查集)

    题意: 有N个学生,编号为0-n-1,现在0号学生感染了非典,凡是和0在一个社团的人就会感染, 并且这些人如果还参加了别的社团,他所在的社团照样全部感染,社团个数为m,求感染的人数. 输入: n代表人 ...

  9. Hacker News排名算法工作原理

    这篇文章我要向大家介绍Hacker News网站的文章排名算法工作原理,以及如何在自己的应用里使用这种算法,这个算法非常简单,但却在突出热门文章和遴选新文章上表现的非常优秀.本质上,这段Hacker ...

  10. wpf控件开发基础

    wpf控件开发基础(3) -属性系统(2) http://www.cnblogs.com/Clingingboy/archive/2010/02/01/1661370.html 这个有必要看看 wpf ...