美文网首页
Servlet 3.0 之 Response

Servlet 3.0 之 Response

作者: Lucky_Micky | 来源:发表于2016-02-16 11:44 被阅读333次

    response对象包含了所有从服务端返回给客户端的信息。在HTTP协议下,这些信息通过HTTP头部或者response的消息体从服务器被传输到客户端。

    Buffering

    为了提高效率,一个servlet容器可以缓存输出到客户端的内容。典型的缓存服务器会把缓存服务默认打开,但是允许servlet指定缓存参数。

    ServletResponse接口里的下列方法允许一个servlet访问和设置缓存参数:

    • getBufferSize
    • setBufferSize
    • isCommitted
    • reset
    • resetBuffer
    • flushBufer

    无论servlet是否正在使用ServletOutPutStream或者Write,上述在ServletResponse接口之上提供的方法让缓存操作都能被执行。

    方法getBufferSize返回正在使用的Buffer的大小。如果没有缓存被使用,这个方法返回int类型的0。

    servlet能够请求通过setBufferSize方法设置的指定大小的buffer。分配的buffer大小不必与servlet请求的大小一样,但是必须不能小于请求的大小。这允许容器重用固定大小的buffer集合,在合适的时机可以提供一个比请求更大的buffer。在用ServletOutputStream 写回任何内容之前,方法setBufferSize必须被调用。如果任何内容被写回,或者response对象被提交,方法setBufferSize抛出IllegalStateException

    方法IsCommitted 返回一个boolean值来标识是否有任何response字节被返回到客户端。方法flushBuffer 强制buffer中的内容被写回到客户端。

    方法reset 在response对象没有被提交之前,清除缓存中的数据。Servlet在reset调用之前设置的header和状态码也必须被清除。如果response没有被提交,而且没有清除headers和状态码,resetBuffer 方法可以清除buffer中的内容。

    如果response被提交,并且resetresetBuffer方法被调用,一个IllegalStateException必须被抛出。response及其相关的buffer将不会被改变。

    当使用一个buffer,容器必须立即把已满buffer的内容刷新到客户端。如果这是发送给客户端的第一份数据,那么response就被认为被提交了。

    Headers

    一个servlet能通过HttpServletResponse 接口的下列方法设置HTTP response的headers:

    • setHeader
    • addHeader

    方法setHeader 用指定的名字和值来设置一个header。之前的header会被新的header替代。如果一个名字对应一个头部值的集合,它的值会被清除并且被新值替代。

    方法addHeader 添加一个header值到指定名字的集合中。如果没有关联此名字的header存在,新的将会被创建。

    Headers可以包含表示一个int或者Date对象数据。下列HttpServletResponse接口的便捷方法允许一个servlet使用正确的格式化类型来设置一个header。

    • setIntHeader
    • setDateHeader
    • addIntHeader
    • addDateHeader

    为了成功地传输回客户端,headers必须在response被提交之前设置好。在response被提交后设置的header将会被servlet容器忽略。

    Servlet程序员负责在response对象中,为servlet生成的内容设置合适的Content-Type头部。HTTP1.1规范不要求在一个HTTP response中设置这个header。当servlet程序员没有设置Content-Type,servlet容器一定不能设置默认的content类型。

    推荐容器使用X-Powered-By HTTP头部来发布它的实现信息。域值应该由一个或者多个实现类型组成,比如Servlet/3.0。容器的补充以及底层的Java平台信息可以被添加到括号里实现类型的后面。容器应该是可配置来覆盖这个header。

    这是X-Powered-By头部的例子。

    • X-Powered-By: Servlet/3.0
    • X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish v3 JRE/1.6.0)

    便捷方法

    下列便捷方法存在于HttpServletResponse 接口中:

    • sendRedirect
    • sendError

    sendRedirect 方法将设置合适的headers和消息体来把客户端重定向到不同的URL。用一个相对URL路径调用这个方法是合法的,但是当前容器必须把相对路径转换成具体的URL传回客户端。如果一个不完整的URI因为任何一个原因不能被转换为一个合法URL,那么这个方法必须抛出IllegalArgumentException

    sendError方法将为返回给客户端的错误消息设置合适的headers和消息体。有一个可选的字符串参数能够传递给这个函数,这个参数能够被应用在消息体中。

    如果response还没有被提交,或者结束,这些方法在提交response时将会有副作用。在这些方法调用之后,不应该再有更多内容输出到客户端了。如果在这些方法调用后,还有数据写到response,这些数据会被忽略。

    如果这些数据被写到response buffer,但是没有返回给客户端(i.e response还没有被提交),response buffer中的数据必须被清除并且被通过这些方法设置的数据替代。如果response已经被提交,这些方法必须抛出IllegalStateException

    国际化

    Servlets应该设置response的区域和字符编码。区域用ServletResponse.setLocale方法来设置。这个方法能被重复地调用,且在response提交之后调用此方法不会有副作用。如果servlet在页面提交之前没有设置区域,容器会使用默认值来决定response的区域,但是并没为与客户端通信制定规范,比如HTTP中的Content-Language 头部。

    <locale-encoding-mapping-list>
      <locale-encoding-mapping>
        <locale>ja</locale>
        <encoding>Shift_JIS</encoding>
      </locale-encoding-mapping>
    </locale-encoding-mapping-list>
    

    如果这个元素不存在,或者没有提供一个映射,setLocale 使用一个依赖容器的映射。setCharacterEncoding,setContentTypesetLocale能重复调用来改变字符编码。在servlet response的getWriter方法已经被调用之后,或者在response提交之后调用此方法对字符编码不会有副作用。
    仅当指定的content type字符串为charset 属性提供一个值时,调用setContentType方法来设置字符编码。
    仅当setCharacterEncodingsetContentType 之前都没有设置字符编码,调用setLocale方法设置字符编码。

    如果在ServletResponse接口的getWriter方法调用或者response被提交之前,servlet没有指定字符编码,会使用默认编码 ISO-8859-1

    如果当前使用的协议提供一种编码方式,容器必须为servlet的writer与客户端交流应用于servlet响应对象的writer的区域和字符编码。使用HTTP时,对于文本媒体类型,字符编码作为Content-Type头部的一部分,那么区域通过Content-Language头部来交流。需要注意的是,如果没有指定content type,servlet字符编码不能通过HTTP头部来交流;然而它仍然用来编码servlet响应对象的writer写回的文本。

    Response对象的闭包

    当response对象被关闭,容器必须立即把response buffer中所有剩余内容刷新到客户端。下列事件标识servlet已经满足了请求并且response对象将会被关闭:

    • servlet的service方法结束了.
    • 由response对象中的setContentLength方法指定的内容的长度大于0并且已经被写到response.
    • 方法sendError被调用.
    • 方法sendRedirect被调用.
    • AsyncContext上的complete方法被调用.

    Response对象的生命周期

    每个response对象仅在一个servlet的service方法范围内,或者在filter的doFilter方法范围内才合法,除非相关的请求对象已经为组件启动了异步处理。如果相关请求上的异步处理开始,请求对象直到complete方法被调用前仍然合法。为了避免创建新response对象的性能消耗,容器通常会重复利用response对象。
    开发者必须意识到,维护一个指向response对象的引用,且与此对应的request对象上的startAsync还没有被调用,那么要是这引用指向上述范围之外会导致无法预测的行为。

    翻译自 Java Servlet Specification
    Version 3.0 Rev a
    Author:Rajiv Mordani
    Date: December 2010

    相关文章

      网友评论

          本文标题:Servlet 3.0 之 Response

          本文链接:https://www.haomeiwen.com/subject/rejykttx.html