Servlet的学习之Response响应对象(3)
本篇来说明响应对象HttpServletResponse对象的最后一点内容。
首先来看响应对象控制浏览器定时刷新,在我的web应用【myservlet】中创建Servlet,在该Servlet中设置响应头,定时刷新的代码很简单:
response.setHeader("refresh", "3 "); //3秒刷新一次
就可告知浏览器3秒刷新一次网页。当然“Refresh”响应头还是可以定时跳转到指定页面,如下代码:
response.setHeader("refresh", "3;url='/myservlet/index.jsp'");
将会在访问我这个Servlet的3秒后访问我的【myservlet】web应用下的index.jsp资源。
之前说过,使用<meta>标签可以模拟响应头,同样在这里可以使用Servlet向客户端写数据时将<meta>标签写入响应数据实体,由浏览器解析后再来控制:
String data = "银魂";
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("<meta http-equiv='refresh' content='3;url=/myservlet/index.jsp' >");
response.getWriter().write(data);
这里请注意:在向响应对象写入任何数据之前,请先设置好使用的编码表,如果在写入数据之后再设置编码表则无效,例如下面代码:
String data = "银魂";
response.getWriter().write(data);
response.setContentType("text/html;charset=UTF-8");
通过查看HttpWathch可以知道,编码表并没有设置成功:

把设置编码表的代码放置在向响应对象写入数据也是不行的,如下:
String data = "银魂";
response.getWriter().write("<meta http-equiv='refresh' content='3;url=/myservlet/index.jsp' >");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write(data);
这样也会设置编码表无效,造成中文乱码问题,所以在向响应对象写入任何数据之前请确保先将编码表设置好。
请求重定向:之前在http协议中学习了响应码302和“Location”响应头可以设置请求重定向。
一个简单的代码示例(web工程名为【myservlet】):
1 response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); //302状态码
2 response.setHeader("location", "/myservlet/index.jsp");
对于不太熟悉HTTP协议的编程人员来说,当然还有更快捷的方式:
response.sendRedirect("/myservlet/index.jsp");
验证:在浏览器中的地址栏中键入该Servlet的地址,浏览器则是会跳转至该web目录下的index.jsp,这个可以从浏览器地址栏上看出。
关于请求重定向中的细节:
一次请求重定向会向服务器发送两次请求。也就是说会产生两次response响应对象和request请求对象;同时浏览器的地址栏是会发生变化的,URL将跳转到重定向后的页面地址。这点和转发不同(在《Servlet的学习(五)》中说过)。
最后再回到response响应对象的getOutputStream方法和getWriter方法,这两个方法在《Servlet的学习(七)》中已经详细介绍了解决中文乱码问题,那么现在我们还需要注意的是:getOutputStream方法和getWriter方法这两个方法相互排斥,不能同时使用。否则会出现如下问题:

也许大家会瞧不起这个问题,认为不就是在一个Servlet中不要同时使用字节流和字符流嘛,注意下就好了。
问题当然不会这么简单,比如在转发中使用不同的IO流还是会出现这种问题的:
假设我的【myservlet】这个web工程中有两个Servlet:ServletResponse1和ServletResponse2。
在ServletResponse1中的代码为:
response.getWriter();
RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/WEB-INF/classes/ServletResponse2");
dispatcher.forward(request, response);
在ServletResponse2中的代码为:
response.getOutputStream();
那么结果是直接部署出错:

在ServletResponse1中将Response对象传递给ServletResponse2中,本身Response就已经调用了获取Writer对象的方法,因此不能再在ServletResponse2中获取OutputStream对象,所以在做转发时要特别注意获得IO流对象。
而将Servlet调用getOutputStream()方法后再转发给JSP文件也是会出错的
比如在ServletResponse1中代码为:
OutputStream out = response.getOutputStream();
RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/index.jsp");
dispatcher.forward(request, response);
而访问这个Servlet会看到:

这是因为在Servlet向JSP中写入数据时默认使用了getWriter()方法获取字符流,然后向JSP中写入数据,这时如果我们在转发JSP之前的Servlet再使用getOutputStream必然会产生冲突。如果想向JSP中传入的必须是使用字节流才能传输的数据,请查验相关解决方案。
Servlet的学习之Response响应对象(3)的更多相关文章
- Servlet的学习之Response响应对象(2)
本篇接上一篇<Servlet的学习之Response响应对象(1)>,继续从HttpServletResponse响应对象来介绍其方法和功能. 使用setHeader方法结合HTTP协议的 ...
- Servlet的学习之Response响应对象(1)
在之前学习了Servlet中的主体结构,包括Servlet的生命周期方法,和非生命周期方法能获取的一些非常重要的对象如ServletConfig.ServletContext对象等,而从这篇开始我们将 ...
- Servlet的学习之Request请求对象(3)
本篇接上一篇,将Servlet中的HttpServletRequest对象获取RequestDispatcher对象后能进行的[转发]forward功能和[包含]include功能介绍完. 首先来看R ...
- Servlet的学习之Request请求对象(2)
在上一篇<Servlet的学习(十)>中介绍了HttpServletRequest请求对象的一些常用方法,而从这篇起开始介绍和学习HttpServletRequest的常用功能. 使用Ht ...
- Django视图函数之request请求与response响应对象
官方文档: https://docs.djangoproject.com/en/1.11/ref/request-response/ 视图中的request请求对象: 当请求页面时,Django创建一 ...
- Servlet的学习之Request请求对象(1)
在本篇中开始对Servlet中的HttpServletRequest请求对象进行学习,请求对象同响应对象一样,我们可以根据该对象中的方法获取例如请求行,请求头和请求实体数据的方法. 在本篇中先对Htt ...
- flask基础之Response响应对象(九)
前言 Response对象负责对客户端的响应,每一个请求都会有一个Response对象,那么它在一个请求的声明周期内是怎么发挥作用的呢? Response对象 响应发生的位置 先回顾一下http请求的 ...
- Response响应对象
1.HttpServletResponse HttpServletResponse是一个定义在Servlet API中的接口,继承自ServletReponse接口,用于封装HTTP响应消息.HTTP ...
- django 获取request请求对象及response响应对象中的各种属性值
django request对象和HttpResponse对象 HttpRequest对象(除非特殊说明,所有属性都是只读,session属性是个例外) HttpRequest.scheme 请求方案 ...
随机推荐
- [Swust OJ 763]--校门外的树 Plus(暴力枚举)
题目链接:http://acm.swust.edu.cn/problem/0763/ Time limit(ms): 1000 Memory limit(kb): 65535 西南某科技大学的校门外有 ...
- Oracle自带的exception
存储过程中自带的exception: --查询人员资料历史 BEGIN SELECT * INTO Po_Sac01 FROM Sac01 WHERE Aac001 = Pi_Aac001 ); EX ...
- django-crispy-forms入门指南
django-crispy-forms 是对django form在html页面呈现方式进行管理的一个第三方插件. 配置: 在INSTALLED_APPS中加入'crispy_forms' djang ...
- 测试css2.1选择器IE6/7/8支持情况,属性选择器/子元素/相邻
环境 xp ie 8 , ietester <!doctype html> <html> <head> <meta charset="utf-8&q ...
- 如何使用银联卡充值美元到BTC-E以及比特币搬砖教程
1,名词解释 搬砖:就是在价格低的平台买入比特币,然后转移到价格高的平台卖出, 一般而言,BTC-E是国外三大比特币交易所中比特币单价最低的一个站,因为其需要用美元充值,相对不方便.之前国内比特币价格 ...
- 函数可以作为Javascript对象(哈希表)的键吗
一般Javascript书在讲解对象时,都指出Javascript中的对象可以作为哈希表,存储键值数据.通常情况下,键为字符串,如果键是数字的话,实际上在内部也会转换为字符串. 比如 var o = ...
- sprintf,你知道多少?
选自<CSDN 社区电子杂志——C/C++杂志>http://emag.csdn.net 2005 年1 月 总第1 期 - 93 -本文作者:steedhorse(晨星)printf 可 ...
- [Unity 3D] Unity 3D 性能优化 (一)
听到过很多用Unity 3D开发游戏的程序员抱怨引擎效率太低,资源占用太高,包括我自己在以往项目的开发中也头疼过.最近终于有了空闲,可以仔细的研究一下该如何优化Unity 3D下的游戏性能.其实国外有 ...
- POJ 2528 QAQ段树+分离
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submitcid=58236#statu ...
- 【iOS】用Layer创建一个三维模型以及拖动
关于CALayer的介绍以及基本属性,在这篇博客中有交代:CoreAnimation —— CALayer 这篇博客讲述简单的通过对layer的transform属性的设置一个CATransform3 ...