本篇来说明响应对象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. git阶段学习总结

    学习git大约有两个星期了,脑子里总算有点干货了,可以拿出来总结一下: git,用于版本控制的,刚开始觉得它是linux下默认的命令,其实也是个工具需要apt-get install git 安装一下 ...

  2. 界面控件 - 滚动条ScrollBar(对滚动条消息和鼠标消息结合讲的不错)

    界面是人机交互的门户,对产品至关重要.在界面开发中只有想不到没有做不到的,有好的想法,当然要尝试着做出来.对滚动条的扩展,现在有很多类是的例子. VS2015的代码编辑是非常强大的,其中有一个功能可以 ...

  3. ios中的任务分段

    工作比较忙,蛮久没有写东西了,今天我要写的是ios中的任务分段.大多数的情况下,我们用不到任务分段,但是如果我们是在执行比较频繁的函数或者这个函数是比较耗时, 某一条件下,我要执行新的任务,并且取消上 ...

  4. 从零開始开发Android版2048 (四) 分数、重置、结束

    这一篇的内容主要是在上一篇的基础上,增加分数计算(包含当前分数和最高分数).游戏结束的推断以及游戏界面的重置这三个部分的功能. 一.分数的计算和保存          首先,2048这个游戏的分数包含 ...

  5. Java 找出四位数的全部吸血鬼数字 基础代码实例

    /**  * 找出四位数的全部吸血鬼数字  * 吸血鬼数字是指位数为偶数的数字,能够由一对数字相乘而得到,而这对数字各包括乘积的一半位数的数字,当中从最初的数字中选取的数字能够随意排序.  * 以两个 ...

  6. 关于C++异常机制的笔记(SEH, try-catch)

    昨天晚上加班解决了一个问题,是由于无法正确的捕获到异常导致的.刚开始用try-catch,但是没法捕获到异常:后面改成SEH异常才解决.因此今天将这个问题重新梳理了一遍,关于try-catch, SE ...

  7. javascript每日一练(七)——事件二:键盘事件

    一.键盘事件 onkeydown触发, keyCode键盘编码 ctrlKey altKey shiftKey 键盘控制div移动 <!doctype html> <html> ...

  8. 08-UIKit(UITableTableViewCell、自定义Cell、xcode调试)

    目录: 1. UITableTableViewCell 2. tag技术 3. 自定义Cell 4. 用nib文件构造自定义的静态表 5. TableView数据模型总结 6. Xcode代码调试 & ...

  9. Android Activity 常用功能设置(全屏、横竖屏等)

    Activity全屏设置 方式1:AndroidManifest.xml <activity android:name="myAcitivty"  android:theme ...

  10. docker学习笔记5:利用commit命令创建镜像 和 删除本地镜像

    一.概述 创建镜像有两种方法,一是用commit命令,二是用dockerfile方法(这个更常用,在下面文章介绍).本章介绍commit方法. 在介绍commit命令前,我们先回顾下对代码的版本控制, ...