HttpServletResponse是专门用于HTTP协议的ServletResponse接口,它用于封装HTTP响应消息,允许操控HTTP协议相关数据,包括响应头和状态码,支持Cookies和session跟踪,HttpServletResponse也定义了一系列用于描述各种HTTP状态码的常量。
WEB服务器回送给WEB客户端的HTTP响应消息分为三部分,状态行、响应消息头 和 消正文(也叫实体内容)。
***WEB响应消息的响应状态行可分为三部分:http版本、状态代码和一条相关的提示信息,如:HTTP/1.1 200 OK
HttpServletResponse中定义了几个用于产生HTTP消息的响应状态行的方法和对应各个响应状态码的常量。***
- 状态码常量:略;
- setStatus(int status)方法:用于设置HTTP响应消息的状态码,并生成响应状态行。由于响应状态行中的状态描述信息直接与状态码相关,而 HTTP 版本由服务器确定,因此,只要通过 setStatus(int status)方法设置了状态码,即可实现状态行的发送。需要注意的是,在正常情况下,Web 服务器会默认产生一个状态码为 200 的状态行。
- sendError(int sc)方法:该方法用于发送表示错误信息的状态码。例如,404 状态码表示找不到客户端请求的资源。response 对象提供了两个重载的 sendError(int sc)方法,具体如下: public
public void sendError(int code) throws java.io.IOException
代码语言:javascript复制 public void sendError(int code,String message)throws java.io.IOException
在上面重载的两个方法中,第一个方法只发送错误信息的状态码,而第二个方法除了发送状态码以外,还可以增加一条用于提示说明的文本信息,该文本信息将出现在发送给客户端的正文内容中。
Servlet 向客户端发送的响应消息中包含响应头字段,由于 HTTP 协议的响应头字段有很多种,因此,HttpServletResponse 接口定义了一系列设置 HTTP 响应头字段的方法
方法声明 | 功能描述 |
---|---|
void addIntHeader(String name,int value) | 这两个方法都是用于设置 HTTP 协议的响应头字段。其中,参数 name 用于指定响应头字段的名称,参数 value 用于指定响 应头字段的值。不同的是,addHeader() 方法可以增加同名的响应头字段(HTTP响应消息中允许同一名称的头字段出现多次),而 setHeader() 方法则会覆盖同名的头字段 |
void setIntHeader(String name, int value) | |
void addIntHeader(String name,int value) | 这两个方法专门用于设置包含整数值的响应头,避免了使用 addHeader() 与 setHeader() 方法时需要将 int 类型的设置值转换为 String 类型的麻烦 |
void setIntHeader(String name, int value) | |
void addDataHeader(String name,long date) | 这两个方法专门用于设置包含日期值的响应头,HTTP响应头中的日期通常都为GMT格式,避免了以毫秒为单位的长整数转换为GMT时间串的麻烦 |
void setDataHeader(String name, long date) | |
void setContentLength(int len) | 设置响应中内容主体的长度。在HTTP servlet中,此方法设置HTTP Content-Length标头。参数:len-一个整数,指定要返回给客户端的内容的长度;设置Content-Length标头 |
void setContentType(String type) | 该方法用于设置 Servlet 输出内容的 MIME 类型,对于 HTTP 协议来说,就是设置 Content-Type 响应头字段的值。例如,如果发送到客户端的内容是 jpeg 格式的图像数据,就需要将响应头字段的类型设置为 image/jpeg。需要注意的是,如果响应的内容为文本,setContentType() 方法还可以设置字符编码,如 text/html;charset = UTF-8 |
void setLocale (Locale loc) | 该方法用于设置响应消息的本地化信息。对 HTTP 来说,就是设置 Content-Language 响应头字段和 Content-Type 头字段中的字符集编码部分。需要注意的是,如果 HTTP 消息没有设置 Content-Type 头字段,则 setLocale() 方法设置的字符集编码不会出现在 HTTP 消息的响应头中,如果调用 setCharacterEncoding() 或 setContentType() 方法指定了响应内 容的字符集编码,则 setLocale() 方法将不再具有指定字符集编码的功能 |
void setCharacterEncoding(String charset) | 该方法用于设置输出内容使用的字符编码,对 HTTP 协议来说,就是设置 Content-Type 头字段中的字符集编码部分。如果没有设置 Content-Type 头字段,则 setCharacterEncoding 方法设 置的字符集编码不会出现在 HTTP 消息的响应头中。setCharacterEncoding() 方法比 setContentType() 和 setLocale() 方法的优先权高,它的设置结果将覆盖 setContentType() 和 setLocale() 方法所设置的字符码表 |
*此外containsHeader方法用于检查某个名称的头字段是否已经被设置。*
响应头消息的实用案例
- Servlet的中文输出问题:浏览器接收到的中文字符并不是中文符号本身,它是某种字符集编码数据。同一中文字符可以用多种字符编码,而浏览器也要使用相应的字符集编码才能显示。浏览器显示网页文档时采用的字符集编码可以通过手工方式设置们也可在HTTP响应消息的Content-Type头字段中指定。作为网站开发人员,应避免让客户手动设置浏览器显示网页所采用的字符编码,这个通过调用setContentType方法就能实现(例如response.setContentType(“text/html;chaeset=GB2312”))。
- 让浏览器定时舒心网页或跳转至其他网页:HTTP协议中定义了一个Refresh头字段,用于高速浏览器多少秒后自动刷新页面。在这个设置值后加分号(;)分隔再指定一个URL地址,就能跳过去访问URL地址的资源了。 response.setHeader(“Refresh”,“2;URL=…”).
- 禁止浏览器缓存当前文档内容:有三个HTTP响应头字段都可以禁止浏览器缓存当前页面,事例如下:
response.setDateHeader("Expires",0);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
- 使用标签模拟响应消息头:HTML语言中专门定义了标签的http-equiv属性来在HTML文档中模拟HTTP响应消息头
发送响应消息体相关的方法
发送响应消息体相关的方法 由于在 HTTP 响应消息中,大量的数据都是通过响应消息体传递的,因此,ServletResponse 遵循以 I/O 流传递大量数据的设计理念。在发送响应消息体时,定义了两个与输出流相关的方法。 1)getOutputStream() 方法 该方法所获取的字节输出流对象为 ServletOutputStream 类型。由于 ServletOutputStream是OutputStream 的子类,它可以直接输出字节数组中的二进制数据。因此,要想输出二进制格式的响应正文,就需要使用 getOutputStream() 方法。 2)getWriter() 方法 该方法所获取的字符输出流对象为 PrintWriter 类型。由于 PrintWriter 类型的对象可以直接输出字符文本内容,因此,要想输出内容全部为字符文本的网页文档,则需要使用 getWriter() 方法。 注意1:虽然 response 对象的 getOutputStream() 和 getWriter() 方法都可以发送响应消息体,但是,它们之间互相排斥,不可同时使用,否则会发生 IllegalStateException 异常。 注意2:虽然Servlet的sercice方法结束后,Servlet引擎会检查这两个方法返回的输出流对象有没有调用close方法,没有会帮忙调一下,但是作为Servlet开发人员最好还是把close方法加上,以便尽快释放相关资源。 3)输出缓存区 Servlet程序输出的HTTP消息的响应正文不是直接发送到客户端,而是首先被写入到了Servlet引擎提供的输出缓存区中,这个缓存区就跟个蓄水池似地,要等被填满或者Servlet程序写完了所有响应内容,缓存区的内容才会被发送到客户端。 setBufferSize方法: 设置期望的输出缓冲区大小 getBufferSize方法: 返回Servlet引擎实际使用的缓冲区大小 flushBuffer方法: 将输出缓冲区内容强制输出到客户端 reset方法: 清空输出缓存区的内容 isCommitted方法: 判断是否提交到了客户端 4)实现动态文件内容下载:当要下载的文件不是真正存在与WEB服务器的文件系统中,而是需要用一个Servlet程序临时在服务器内存中动态产生后再传送到客户端。 servlet程序必须告诉浏览器其所输出的内容的类型不是普通文本文件或者HTML文件,而是一个淘宝村到本地的下载文件,这就需要HttpServletResponse.setContentType方法来设置Content-Type头字段的值为浏览器无法使用某种方式活着激活某种程序来处理的MIME类型,例如"application/octet-stream"; 通过HttpServletResponse.setHeader方法设置Content-Disposition头的值为"attachment;filename=文件名"; 因为附件可以是各种文件类型文件,需将附件文件内容传至客户端,其中内容当作二进制处理,所以当调用HttpServletResponse.getOutputStream方法返回的ServletOUtputStream对象来想客户端写入附件内容 5)图像访问计数器:统计和显示页面的访问次数是一个常见的WEB应用,因为在网页每次被访问时,页面的访问次数都要发生改变,所以这个功能必须通过服务器端的程序来实现。具体内容:略;
请求重定向与请求转发
- 在Servlet程序中,有时需要调用另外一个资源来对浏览器的请求进行响应,这可以通过两种方式实现:其中一种是调用RequestDispatcher.forward方法实现的请求转发,另一种是调用HttpServletResponse.sendRedirect方法实现的请求重定向。1)1)1)1)RequestDispatcher接口:在Servlet API中定义的接口,它定义了RequestDispatcher实例对象的方法 RequestDispatcher接口中定义了两个方法:forward方法和include方法,分别用于将请求转发到RequestDispatcher对象封装的资源 和 将RequestDispatcher对象封装进资源作为当前响应内容的一部分包含进来。 ServletContext接口中定义了获取RequestDispatcher对象的方法:getRequestDispatcher方法、getNameDispatcher方法,具体略。
- 用include方法进行包含:略
- 用forward方法实现请求转发:略
- 请求转发与请求重定向的比较 RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect 方法还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。 如果传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于服务器的根目录;如果创建RequestDispatcher对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。 调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;调用RequestDispatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。 HttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求;RequestDispatcher.forward方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。 RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。