Servlet&JSP学习系列(3) - Response消息

Servlet是基于HTTP协议的,因而深入了解HTTP协议的消息格式,对理解Servlet有很大的帮助。事实上,HttpServletResponse就是对HTTP响应消息的一种封装。

Reponse的消息格式如下:
[HTTP-Version][SP][Status-Code][SP][Reason-Phrase][CRLF] // Status Line
[headers(key: value)]*
[CRLF]
[Message-Body]

注:SP为空格
CRLF为回车换行
如:
HTTP/1.1 200 OK
Content-Type: text/html
Header2: …
….
HeaderN: …
(blank line)
<!DOCTYPE …>
<html>
<head>….</head>
<body>

</body>
</html>

在Response消息中,由状态行,消息头,消息体构成。状态行包含HTTP版本号(由服务器决定),状态码和一段对当前状态码简短的描述。一般消息体是由用户自定义填写的(消息体可以为空,如Head请求),而状态头部分系统根据用户操作而自动设置,用户可以自己设置状态头(注:状态头除了Content-Type外,其他的都是可选的)。浏览器会根据状态码和消息头做一些特定的操作,如400状态码会显示错误的请求的消息(用户可以自定义该消息内容),Content-Type: application/vnd.ms-excel表示显示的excel表格等。
下面重点介绍一些状态码和消息头。

状态码:
对正常情况下,我们并不需要直接设置状态码,服务器会自动设置状态码为200(OK)。对非正常的情况,我们需要手动设置状态码,可以调用response.setStatus(int)来设置状态码,也可以调用response.sendRedirect(String url)或response.sendError(int code, String message)函数来设置以影响状态码(分别是302(Found)和404(Not Found)。需要特别注意,由于没有规定服务器需要缓存响应消息,因而一定要在设置消息体之前设置状态码。

HTTP1.1中的状态码包含5种类型:
1xx :信息性的消息,该响应消息不包含消息体,且在HTTP1.0中没有定义这样的消息。它表示浏览器应该采取其他的动作。
2xx :表示请求成功。
3xx :表示浏览器需要采取进一步的操作才能完成请求。
4xx :表示客户端产生的错误(如消息格式的错误)。
5xx :表示服务器端产生的错误。

1. 100 Continue response.SC_CONTINUE
当服务器接受到值为100-continue的Expect请求头时,表示客户端在询问是否可以在随后的请求中发送附加文件。此时服务器应该以状态100(response.SC_CONTINUE)回应,以告诉客户端可以继续;或者发送417(response.SC_EXPECTATION_FAILED)以告诉客户端不接受该文档。

2. 200 OK response.SC_OK
Servlet的默认值,表示请求一切正常。

3. 202 Accept response.SC_ACCEPT
表示请求已经接受但尚未处理完成。

4. 204 No Content response.SC_NO_CONTENT
表示要求浏览器继续显示之前的文档,因为文档没有更新。在处理用户经常刷新的情况下,这个行为比较有有用,以减少服务器的负担和网络的流量。

5. 205 Reset Content response.SC_RESET_CONTENT
表示没有新文档,但是浏览器应该重置文档。该状态码主要用来指示浏览器清楚表单的字段。这是HTTP1.1新引入的状态码。

6. 301 Moved Permanently response.SC_MOVED_PERMANENTLY
表示请求的文件已经永久的被移动到别处,浏览器需要跳转到新的URL(该URL会在Location的消息头中给出)。

7. 302 Fond response.SC_ED_TEMPORARILY
该值类似301,只是原侧上,将该Location消息头看作是非永久性的替代。在实际中,多数浏览器同等的对待301和302。在Servlet中,除了setStatus函数,还可以调用sendRedirect方法来生成该状态码。
注:该状态码的HttpServletResponse中定义的常量为SC_MOVED_TEMPORARILY,而不是期待的SC_FOUND。该消息是在HTTP1.0中定义的。

该状态码需要和刷新区别开来:刷新也可以完成自动跳转到其他页面,但是刷新会在浏览器的地址栏中临时性的显示回传的浏览器的包含刷新命令的地址,而重定向不会显示这个中间地址,而会直接跳转。

那么我们为什么需要使用重定向这个命令呢?它主要有三个方面的应用。
1. 计算目的地址
有些时候,我们需要分析用户的请求后才能知道用户想要去的目的地址。例如我们可以根据用户选择的城市而决定返回什么样的页面。

2. 跟踪用户的行为
为了分析用户的点击行为(如统计用户的点击量等),我们不能将直接的链接发给用户,而是可以发送一个间接的链接,在做完一些分析以后才将他们重定向到实际的页面。例如一些搜索引擎就是使用这种技巧来做一些统计的。

3. 执行边界效应
有些时候我们可能会遇到这样的需求,就是希望在将用户重定向到其他站点上之前设置一些cookie值,此时就可以在调用sendRedirect方法之前设置响应的cookie即可。

可以通过两种方式来实现重定向:setStatus()和setHeader()的组合以及sendRedirect()方法。使用sendRedirect()方法有以下好处:简单、Servlet会自动构建含有该连接的页面,以引到那些不能处理重定向信息的老版本的浏览器、可以使用相对地址,Servlet会自动将他们转换成对应的绝对地址。

一般认为仅当最初的请求为GET时,浏览器才应该自动执行重定向,且重定向时也使用GET方法(即使是POST的重定向,重定向请求也是用GET方法请求)。参见303和307.

8. 303 See other response.SC_SEE_OTHER
类似于301和302。但该状态表示不管在GET和POST方法下,都继续重定向。在RFC2616中规定重定向请求需要用GET方法获取,以Servlet与JSP编程中的介绍,好像最初方法为POST时,重定向也是用POST请求,经过IE测试,应该在重定向的时候也是使用GET方法的。比较307.

9. 304 Not Modified response.SC_NOT_MODIFIED
在客户已经拥有缓冲的文档时,它可以提供If-Modified-Since请求报头来执行条件请求,表示仅当文档在制定的日期发生改变之后,才读取文档。Servlet一般不直接设置这个状态值,取而代之的是实现getLastModified方法,其他由Servlet内部自动处理。

10. 307 Temporary Redirect response.SC_TEMPORARY_REDIRECT
该状态与302状态相同。引入该状态值是为了消除二义性。因为许多浏览器在最初为POST的请求下的302状态值,也进行了重定向。而307的状态值只有在最初为GET请求的时候才重定向,而在最初为POST请求时不进行重定向。只有在303响应是,才都进行重定向。

以上是Servlet与JSP核心编程中给出的解释,但是经过测试后发现,在307状态码在GET和POST请求中都会进行重定向,并且在会保留原来请求内容,而其他状态值(302,303)则不会。

11. 400 Bad Request response.SC_BAD_REQUEST
标明客户请求中含有语法错误。

12. 401 Unauthorized response.SC_UNAUTHORIZED
表示客户在访问含有密码保护的页面时,给出的Authorization请求报头中的身份标识错误。

13. 403 Forbidden response.SC_FORBIDDEN
表示没有权限读取服务器中的相关资源。

14. 404 Not Found response.SC_NOT_FOUND
表示在给定的地址中找不到资源。这是一个常用的状态值,因而Servlet提供了sendError方法来设置该状态值,sendError方法还可以定制显示的消息值。但是一般会为错误设置单独的错误页面以增加友好性。

15. 405 Method Not Allowed response.SC_MOETHOD_NOT_ALLOWED
表示给定的资源不允许使用给定的请求方法来访问。

16. 415 Unsupported Media Type response.SC_UNSUPPORTED_MEDIA_TYPE
表示服务器无法处理请求附加文件的类型。

17. 417 Expectation Failed response.SC_EXPECTION_FAILED
如果服务器收到值为100-continue的Expect请求报头时,表示客户程序在询问是否可以在后即请求中发送附加的文档。此时,服务器可以发送471状态码告诉客户程序服务器不接受该文档,或者100告诉客户程序继续进行。

18. 500 Internal Service Error response.SC_INTERNAL_SERVICE_ERROR
表示服务器内部错误的状态。

19. 501 Not Implemented response.SC_NOT_IMPLEMENTED
表示服务器没有实现客户的请求方法。

20. 503 Service Unavailable response.SC_SERVICE_UNAVAILABLE
表示服务器不能响应客户程序的请求。如服务器维护或超负荷工作状态下。服务器可以提供Retry-After报头以告诉客户程序何时重试。

21. 505 HTTP Version Not Supported response.SC_HTTP_VERSION_NOT_SUPPORTED
表示服务器不支持请求行中给出的HTTP版本。

同Request消息一样,Servlet为Response消息头提供了一些常用类型的消息头设置函数以及通用的消息头设置函数。如通用函数:
setHeader(String headerName, String headerValue)
setDateHeader(String header, long milliseconds)
setIntHeader(String header, int headerValue)
由于HTTP允许相同的报头名多次出现,而setxxx函数会替换原来存在的同名报头,因而Servlet提供了响应的addxxx方法以处理这种情况。同时也提供了containHeader的检查函数。

常用类型的消息头设置函数:
setContentType(String mineType) 设置Content-Type的报头值
setContentLength(int length) 设置Content-Length报头值
addCookie(Cookie c) 向报头插入一个cookie。由于一般响应消息都会有多个cookie行,因而没有对应的setCookie方法。
sendRedirect(String address) 设置状态码为302,同时设置Location报头。

一些常用的报头:
1. Allow
指示服务器支持的请求方法(GET,POST等)。在405(Method Not Allowed)的响应报文中需要设置该报文头。Servlet默认的色vicefangfa自动为OPTIONS请求生成这个报头。

2. Cache-Control
指示浏览器在什么环境下可以安全的缓存文档。其取值可以有
public 缓存在共享缓存中
private 只能存储在私有缓存中
no-cache 不能被缓存。服务器还可以指定”no-cache=”header1, header2….”来规定在缓存响应文档是应该略去的报头。注:老版本中通过Pragma来完成这个任务,因而一般会将Cache-Control和Pragma都设置为no-cache。
no-store 不要缓存文档,甚至不应该将他存储在磁盘上的临时目录中。
must-revalidate 每次使用文档时,客户程序都必须与原来的服务器(而非仅仅中间代理)重新验证文档。
proxy-revalidate 除了只适用于共享缓存意外,这个报头和must-revalidate相同。
max-age 在xxx秒之后该文档被认为无效。这是Expires报头的替代,但只使用HTTP1.1客户程序。如果max-age和Expires同时存在,那么max-age优先。
s-max-age 共享缓存在xxx秒之后被视为无效。

3. Connection
指示浏览器是否使用持续性HTTP连接。close值为表示为否,而keep-alive只表示是(HTTP1.1的默认值)。然而一般持续性连接需要Content-Length响应报头,因而如果不使用持续性连接,可以省略Content-Length值即可,因而不需要显示的使用Content-Length的值。

4. Content-Disposition
指示浏览器询问用户将响应文件存在的文件名和位置。其格式如下:
Conent-Disposition: attachment; filename=some-file-name
当服务器想客户发送非HTML响应时(如jpeg文件,Excel文件等),该报头比较有用。

5. Conent-Encoding
指示页面在传输过程中的编码方式(如gzip、compress等)。浏览器可以根据该信息对文档进行反编码。用gzip也锁文档能够极大的节省传输时间。

6. Content-Language
指示文档所使用的语言。该值应该是标准的语言编码,如en,en-us等。在RFC1766中包含了语言编码的详细信息。在IE中,可以在Internet选项中的常规选项卡中的语言按钮中选择当前使用的语言。

7. Content-Length
指示响应中的字节数。可以调用response.setContentLength()方法来设置。它和Connection密切相关。

8. Content-Type
指示响应文档中的MIME(Multipurpose Internet Mail Extension)类型以及字符编码类型(默认为ISO-8859_1(Latin))。如:
response.setContentType(“text/html; charset=ISO-8859_1(Latin)”)
常见的MIME类型如:application/pdf, application/vnd.ms-excel, application/msword, text/html, text/css等。更多的MIME类型可以参考RFC1521和RFC1522(可以在http://www.rfc-editor.org中查找)。

9. Expires
设置响应内容的过期时间。优先级Cache-Control更高。

10. Last-Modified
标明文件的最后修改日期。可以和If-Modified-Since请求报头结合使用。

11. Location
指示浏览器自动重新连接的地址。一般在状态码为3xx的响应报文中设置该值。

12. Progma
将值设置为no-cache,指示HTTP1.0客户端不要缓存文档,在HTTP1.1中用Cache-Control: no-cache来替代。一般HTTP1.0对该标记的支持并不一直,因而通常通过Expires设置过期日期来实现该任务。

13. Refresh
指示浏览器的刷新时间(以秒为单位)。也可以设置在刷新后进入其他页面(如闪屏的效果):response.setHeader(“Refresh”, “5; URL=http://www.google.com”);

14. Retry-After
同503(Service Unavailable)响应状态结合使用,以通知浏览器在多少时间后可以重复请求。

15. Set-Cookie
设置与一个页面相关的cookie值。每一个cookie都要有一个单独的Set-Cookie报头。

16. WWW-Authenticate
和401(Unauthorized)状态代码一同使用。它告诉浏览器,客户应该在Authorization报头中提供那种类型(BASIC或DIGEST)和域。

你可能感兴趣的:(应用服务器,jsp,servlet,浏览器,Excel)