2014-02-23 115 views
4

我明白,doHead方法不会通过http发送主体,但doGet不会。 这两者之间有明显的区别吗? 在此先感谢。doGet和doHead方法之间的区别

+0

请参阅[HTTP方法定义](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html)。 –

回答

7

简短的回答

HEAD只发送回相同的头信息对应的GET请求会做,但没有实体主体。 GET将发送相同的头文件和实体主体。当然,在罕见/可争议的情况下,GET会在它的内容中没有发回任何东西,那么GET和HEAD的行为就会类似。

HTTP The Definitive Guide补充说:

这允许客户端来检查资源的标题,而无需实际获取资源 。使用HEAD,您可以:

  • 找出有关某个资源(例如,确定其类型)而不知道它。
  • 通过查看响应的状态代码来查看对象是否存在。
  • 通过查看标题来测试资源是否已被修改。

服务器开发人员必须确保返回的头正好是 那些GET请求将返回的头。 HEAD方法也是HTTP/1.1合规性所需的 。

所以,doHead是否调用doGet可能只是一个实现细节,但如果是这样,则doHead将需要发送响应之前剥离的doGet身体。但是,这种实现效率不高,因为理想情况下,doHead不应产生执行整个doGet请求以确定要发回哪个头的困难。

虽然某些标题的计算可能会造成困难。例如,“Content-Length”标题意味着我们需要知道实际资源的大小,因此HEAD可能需要“获取”资源以确定相应GET请求的实际字节大小,但它不会负担该网络实际上将资源发送回去,虽然它可能已经使服务器检索资源以确定要发送回哪些头(即,内容长度,内容类型,内容语言等)

龙答案

HTTP specification

9.4 HEAD

HEAD方法与GET相同,只是服务器不得在响应中返回消息主体 。 HTTP头中包含 的元信息响应于HEAD请求应该与响应GET请求发送的信息相同 。此方法可用于获取有关 请求隐含的实体的元信息,而不会传输实体主体本身。此方法是 经常用于测试超文本链接的有效性,可访问性, 和最近的修改。

对于HEAD请求的响应可能是可缓存的,这意味着响应中包含的信息可以用来从该资源更新以前缓存的实体 。如果新字段值 指示高速缓存实体不同于当前实体(因为 将通过Content-Length,Content-MD5,ETag或Last-Modified中的改变来指示),则高速缓存必须将高速缓存条目陈旧。

而对于GET它说:

9.3 GET

GET方法意味着检索的任何信息(以一个 实体的形式)由请求URI来标识。如果Request-URI引用数据产生过程,则产生的数据应作为响应中的实体而不是 过程的源文本返回,除非该文本恰好是处理。

GET方法改变为 “有条件GET” 的语义,如果 请求消息包括一个If-Modified-由于,如果未改性的-由于, 如果-匹配,如果-无 - 匹配,或者如 - 范围标题字段。条件GET 方法请求仅在条件标头字段描述的 环境下传输实体。 条件GET方法旨在通过允许缓存实体刷新而不需要多个 请求或传输已由客户端持有的数据,来减少不必要的网络使用量 。

如果 请求消息包含Range标头字段,则GET方法的语义将更改为“部分GET”。如部分 14.35中所述,部分GET请求 仅实体的一部分被转移。部分GET方法旨在通过允许完成部分检索的实体来完成 而不传送已由客户端持有的数据来减少不必要的网络使用。

到GET请求的响应是可高速缓存当且仅当用于表单时,它满足了部分13

见15.1.3节为安全考虑描述的用于HTTP缓存的 要求。

如果read the source code for javax.servlet.http.HttpServlet你可以看到,它的文件说:

接收来自受保护的服务方法的HTTP HEAD请求和 处理请求。当客户端想要 只看到响应的标题(如Content-Type或Content-Length)时,客户端会发送HEAD请求。 HTTP HEAD方法对 响应中的输出字节进行计数,以精确设置Content-Length标头。如果您覆盖此方法 ,则可以避免计算响应正文并直接设置 响应标头以提高性能。确保您编写的doHead方法既安全又幂等(即,对于一个HTTP HEAD 请求, 可以保护自己不被多次调用)。如果HTTP HEAD请求格式不正确,则头部 会返回HTTP“错误请求”消息。

和默认的方法实现如下所示:

protected void doHead(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException 
{ 
    NoBodyResponse response = new NoBodyResponse(resp); 
    doGet(req, response); 
    response.setContentLength(); 
} 

如果您NoBodyResponse阅读代码,你会看到,这只是其输出流丢弃所有数据的响应,只是计数字节确定相应的GET响应的正确Content-Length。

所以,这就是Servlet规范提出的如何生成有效HEAD响应的方式。只要遵守HTTP规范指南,您可以重写此行为以使其更有效。

+0

我在某个地方读过一些叫做doGet的地方,这可能让我感到困惑。不过得到它谢谢 – Rollerball

+0

@滚球: - 是的你是正确的。 HttpServlet类的doHead方法调用doGet方法,并仅将响应的标题返回给客户端。 –

+0

@Rollerball: - 如果你想要,你可以通过使用java.net.Socket或java.net.URL类对servlet进行定制的doHead请求来测试。 –

1

doGet()用于当您要截取HTTP GET请求时。而

DoHead文档:

从受保护的服务方法接收一个HTTP HEAD请求和 处理该请求。当客户端想要 只看到响应的标题(如Content-Type或Content-Length)时,客户端会发送HEAD请求。 HTTP HEAD方法对 响应中的输出字节进行计数,以精确设置Content-Length标头。

如果您覆盖 这种方法,您可以避免计算响应正文并直接设置 响应标头以提高性能。确保您编写的doHead方法既安全又幂等(即,对于一个HTTP HEAD 请求, 可以保护自己不被多次调用)。

如果HTTP HEAD请求格式不正确,那么doHead 将返回HTTP“错误请求”消息。