Servlet中response对象Commit状态的分析
response是服务端对客户端请求的一个响应,其中封装了响应头、状态码、内容(也就是最终要在浏览器上显示的HTML代码或者其他数据格式)等。
服务端在把response提交到客户端之前,会使用一个缓冲区,并向该缓冲区内写入响应头和状态码,然后将所有内容flush(flush包含两个步骤:先将缓冲区内容发送至客户端,然后将缓冲区清空)。
这就标志着该次响应已经committed(提交)。
对于当前页面中已经committed(提交)的response:
就不能再使用这个response向缓冲区写任何东西 。(原文这里可能有错误)
不可以再进行send***这类发送响应内容的操作(因为响应已经提交给客户端),
可以使用set***这类设置响应内容的函数(设置后无效,因为响应已经提交给客户端),
实测可以继续进行页面内容的输出(--此处存疑--不能理解--实测(执行response.getWriter().close()后会导致后续输出无效,但不会爆异常)),
实测可以进行request.getRequestDispatcher(“”).include(request, response);,
实测不可以进行request.getRequestDispatcher(“”).forward(request, response);(会抛出IllegalStateException异常Cannot forward after response has been committed),
(注:以为JSP中,response是一个JSP页面的内置对象,所以同一个页面中的response.XXX()是同一个response的不同方法,只要其中一个已经导致了committed,那么其它类似方式的调用都会导致 IllegalStateException异常)。
导致 response 状态变为 committed 的原因:
send***这类方法:向客户端发送状态码或重定向会直接提交响应。
刷新缓存:当response对象缓存区满时,或者使用response对象的flushbuffer方法会刷新response对象的缓存导致响应提交。
转发:将未提交的response通过forward转发可能会在转发目标的处理流程内被提交(include转发不会)。
forward指令和include指令很相似,它们都采用方法来导入目标。
执行forward指令时,response必须未提交,目标获得的response与原Servlet中是同一个(ResponseFacade对象)。原先存放在response对象中的内容将会自动被清除,目标可以直接发出响应,之后程序流程回到原Servlet转发处继续执行,但是原Servlet似乎连页面内容都不可输出了。
而执行include指令时,目标获得的response与原Servlet中不是同一个(被换成了一个ApplicationHttpResponse对象,让目标无法对源请求做出实质响应,但是该对象进行提交操作后会导致原Servlet中的response对象也变为已提交,但仍然可以进行页面输出)。原Servlet把目标产生的响应的内容部分包含到自身响应的内容中,目标改变响应消息的状态码和响应头的语句执行结果将被忽略(即被调用的Servlet的响应只有内容部分会并入原Servlet的响应的内容部分中)。
关于forward和include的详细分析不在此处深究。
关于JSP中的flushBuffer
每一个JSP页面都有一个缓冲区,默认的缓冲区大小为8KB,如果缓冲区被占满的话,web服务器就会自动将response 进行commit,然后清空缓冲区(即flush)。
JSP内置对象out相关方法:
public abstract void clear() throws java.io.IOException | 清除缓冲区中的内容。如果缓冲区已经被刷新,clear()方法将抛出IOException异常 |
public abstract void clearBuffer() throws java.io.IOException | 清除缓冲区中的当前内容。这个方法和clear()方法的区别是,如果缓冲区已经被刷新,这个方法不会抛出IOException异常 |
public abstract void close() throws java.io.IOException |
刷新缓冲区,关闭输出流。注意,我们在编写JSP页面时,不需要显式地去调用这个方法,因为在JSP容器所生成的代码中会自动包含对close()方法的调用。 |
public abstract void flush() throws java.io.IOException | 刷新缓冲区,两个步骤:1,提交response 2.清空缓冲区 |
public int getBufferSize() | 获得缓冲区大小,同response.getBufferSize()相同 |
public abstract int getRemaining() | 获得缓冲区中未使用的字节数 |
public boolean isAutoFlush() | 判断out对象是否是自动刷新 <%@ page autoFlush="true" %> <%--Default--%> |
内置对象response相关方法:
response.isCommitted() | 确认response是否已经committed |
response.flushbuffer(); | 同out.flush相同 |
增大缓冲区大小:
<%@ page buffer="10kb" %> |
文参考:https://www.cnblogs.com/ismallboy/p/6785328.html
Servlet中response对象Commit状态的分析的更多相关文章
- Servlet中Response对象应用1(输出简单文字、实现文件下载)
通过response对象可以实现很多功能,下面的代码都是在myeclipse上实现过的,整理下路,以备后用. response对象应用1 1向客户端发送简单消息 A利用已经声明的对象,调用其getOu ...
- Servlet中Response对象应用2(输出随机验证码图片)
预期结果如图: 可用于登陆界面的验证 需要使用random类和绘画相关的几个类.以及imageio的内容. import java.awt.*; import java.awt.image.Buffe ...
- jsp的C标签一般使用方法以及js接收servlet中的对象及对象数字
jsp的C标签一般使用方法以及js接收servlet中的对象及对象数组 由于现流行的javaWeb框架提倡前后端分离,比如在SpringMvc中已经很少写servlet的一些东西:目前 前端jsp中大 ...
- Hibernate中的对象有三种状态
Hibernate中的对象有三种状态: 瞬时状态 (Transient),持久状态 (Persistent), 1. 脱管状态 (Detached) 1. 1. 瞬时状态 (Transient) 由 ...
- Servlet中response、request乱码问题解决
Java Web(二) Servlet中response.request乱码问题解决 三月不减肥,五月徒伤悲,这就是我现在的状态,哈哈~ 健身.博客坚持. --WH 一.request请求参数出现 ...
- jsp九大内置对象与servlet中java对象
jsp九大内置对象 request对象 : getParameter(String name)获取表单提交的数据 getParamegerNames() 获取客户端提交的所有参数名 getAttri ...
- Java Web之Servlet中response、request乱码问题解决
Java Web之Servlet中response.request乱码问题解决 一.request请求参数出现的乱码问题 get请求: get请求的参数是在url后面提交过来的,也就是在请求行中, ...
- (转)Hibernate框架基础——在Hibernate中java对象的状态
http://blog.csdn.net/yerenyuan_pku/article/details/52760627 在Hibernate中java对象的状态 Hibernate把对象分为4种状态: ...
- Servlet之Response对象
下面的方法可用于在 Servlet 程序中设置 HTTP 响应报头.这些方法通过HttpServletResponse 对象可用. 1 String encodeRedirectURL(Stri ...
随机推荐
- 洛谷P1306 斐波那契公约数
题目描述 对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在有一个很“简单”问题:第n项和第m项的最大公约数是多少? 输入输出格式 输入格式: 两个正整 ...
- Redis事件库源码分析
由于老大在新项目中使用redis的事件库代替了libevent,我也趁着机会读了一遍redis的事件库代码,第一次读到“优美,让人愉快”的代码,加之用xmind制作的类图非常帅,所以留文纪念. Red ...
- 第13篇 PSR-2代码样式
这个规范原文如下: 1. Overview Code MUST follow a "coding style guide" PSR [PSR-1]. Code MUST use 4 ...
- 蓝桥杯 算法训练 ALGO-60 矩阵乘法
算法训练 矩阵乘方 时间限制:1.0s 内存限制:512.0MB 问题描述 给定一个矩阵A,一个非负整数b和一个正整数m,求A的b次方除m的余数. 其中一个nxn的矩阵除m的余数得到的仍是一个 ...
- git 本地文件里内容 操作记录
本地环境文件合并分支(以下的都分别 commit提交了的) [一.分支[追加] 和 [新增] 新信息 合并主线 情景] 分支内容: dr.find_element_by_id("su&qu ...
- 分布式锁之三:mysql实现-待整理
下面我们来看下开源dubbo推荐的业界成熟的zookeeper做为注册中心, zookeeper是hadoop的一个子项目是分布式系统的可靠协调者,他提供了配置维护,名字服务,分布式同步等服务.对于z ...
- Vue.js:计算属性
ylbtech-Vue.js:计算属性 1.返回顶部 1. Vue.js 计算属性 计算属性关键词: computed. 计算属性在处理一些复杂逻辑时是很有用的. 可以看下以下反转字符串的例子: 实例 ...
- PHP通过引用传递参数
<?php function add_some_extra(&$string) // 引入变量,使用同一个存储地址 { $string .= 'and something extra.' ...
- maven(基础介绍一)
maven:提供的作用有以下几点: 1 jar包依赖 这个也许会maven最突出的特点了使用maven不需要上网单独下载jar包,只需要在配置文件pom.xml中配置jar包的依赖关系,就可以自动的下 ...
- rpm --import /etc/pki/rpm-gpg/RPM* 有什么用?
今天用yum安装软件,遇到了Could not open/read file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL问题,为了加深印象,特别搜索了RPM-GPG-K ...