本篇来说明响应对象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)的更多相关文章

  1. Servlet的学习之Response响应对象(2)

    本篇接上一篇<Servlet的学习之Response响应对象(1)>,继续从HttpServletResponse响应对象来介绍其方法和功能. 使用setHeader方法结合HTTP协议的 ...

  2. Servlet的学习之Response响应对象(1)

    在之前学习了Servlet中的主体结构,包括Servlet的生命周期方法,和非生命周期方法能获取的一些非常重要的对象如ServletConfig.ServletContext对象等,而从这篇开始我们将 ...

  3. Servlet的学习之Request请求对象(3)

    本篇接上一篇,将Servlet中的HttpServletRequest对象获取RequestDispatcher对象后能进行的[转发]forward功能和[包含]include功能介绍完. 首先来看R ...

  4. Servlet的学习之Request请求对象(2)

    在上一篇<Servlet的学习(十)>中介绍了HttpServletRequest请求对象的一些常用方法,而从这篇起开始介绍和学习HttpServletRequest的常用功能. 使用Ht ...

  5. Django视图函数之request请求与response响应对象

    官方文档: https://docs.djangoproject.com/en/1.11/ref/request-response/ 视图中的request请求对象: 当请求页面时,Django创建一 ...

  6. Servlet的学习之Request请求对象(1)

    在本篇中开始对Servlet中的HttpServletRequest请求对象进行学习,请求对象同响应对象一样,我们可以根据该对象中的方法获取例如请求行,请求头和请求实体数据的方法. 在本篇中先对Htt ...

  7. flask基础之Response响应对象(九)

    前言 Response对象负责对客户端的响应,每一个请求都会有一个Response对象,那么它在一个请求的声明周期内是怎么发挥作用的呢? Response对象 响应发生的位置 先回顾一下http请求的 ...

  8. Response响应对象

    1.HttpServletResponse HttpServletResponse是一个定义在Servlet API中的接口,继承自ServletReponse接口,用于封装HTTP响应消息.HTTP ...

  9. django 获取request请求对象及response响应对象中的各种属性值

    django request对象和HttpResponse对象 HttpRequest对象(除非特殊说明,所有属性都是只读,session属性是个例外) HttpRequest.scheme 请求方案 ...

随机推荐

  1. Android Support Library更新到v22.1之AppCompat新特性

    构建一个可以跑在不同版本 Android 平台的软件,是非常复杂和耗时的.为了解决这个问题,Android 推出了 Android Support Library (安卓兼容包),让新的UI控件也可以 ...

  2. td

    http://jameswxx.iteye.com/blog/1041173 http://crane-ding.iteye.com/blog/968862 http://www.ibm.com/de ...

  3. Struts2 学习笔记16 struts标签 part2

    接下来说一下if标签.下面是结果图. <li><s:if test="#parameters.age[0]<0">error!</s:if> ...

  4. MySQL具体解释(5)-----------函数超全总结

    mysql函数大全   对于针对字符串位置的操作.第一个位置被标记为1. ASCII(str) 返回字符串str的最左面字符的ASCII代码值. 假设str是空字符串,返回0.假设str是NULL,返 ...

  5. Android的BUG(二) - SurfaceTexture中的野指针

    当初遇到这个bug,是不定期的低概率出现,最后找到一个比较容易重现的步骤: 启动系统 然后进google +  新建一个帐号(注意是新建一个帐号)  没几步就重启了 这个BUG,一开始追踪也是无头绪的 ...

  6. C++变量(C++变量定义、变量赋值、命名规则)

    其实在前面的例子中已经多次用到了变量.在程序运行期间其值可以改变的量称为变量.一个变量应该有一个名字,并在内存中占据一定的存储单元,在该存储单元中存放变量的值.请注意区分变量名和变量值这两个不同的概念 ...

  7. 高级UIKit-02(文件操作)

    [day3_1_Sandbox]:沙箱的介绍 snadbox沙箱沙盒 沙箱根目录下的几个文件夹: 1.应用名称.app存放应用程序的素材 2.Documents:存放应用运行时需要用到的数据(关键性数 ...

  8. xp对opengl的支持问题

    我在项目中遇到的xp显示问题是因为xp对opengl的支持问题,是通过void QCoreApplication::setAttribute(Qt::ApplicationAttribute attr ...

  9. window批处理-3.go

    go: 控制批处理中的命令运行流程 命令格式: go label lable--行号 demo bat @echo off echo 跳过中间.运行最后 goto last type a.txt :l ...

  10. 机器时代的中国字幕(Automata.2014.720p.WEB-DL.DD5.1.H264-RARBG.srt)

    看字幕.再也看不下去.自己翻译的位 评价的探讨 1 00:01:58,452 --> 00:02:02,088 人工增雨 期限为32分钟16第二 2 00:02:02,089 --> 00 ...