doGet和doHead方法之间的区别

时间:2014-02-23 10:03:22

标签: java servlets methods

据我所知,doHead方法不会通过http发送正文,但是doGet也没有。 这两者之间有明显的区别吗? 提前谢谢。

2 个答案:

答案 0 :(得分:7)

简短回答

HEAD只返回相应的GET请求将执行的相同标头信息,但没有实体主体。并且GET将发送相同的头和实体主体。当然,在罕见/有争议的案件中,GET不会在其身上发回任何内容,那么GET和HEAD的行为也会类似。

这本书HTTP The Definitive Guide补充说:

  

这允许客户端在没有的情况下检查资源的标头   必须实际获得资源。使用HEAD,您可以:

     
      
  • 了解资源(例如,确定其类型),而不是获取资源。
  •   
  • 通过查看响应的状态代码来查看对象是否存在。
  •   
  • 通过查看标题来测试资源是否已被修改。
  •   
     

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

因此,doHead调用doGet是否只是一个实现细节,但如果是这样,doHead需要在发送响应之前删除doGet的正文。但是,这种实现效率很低,因为理想情况下doHead不应该导致执行整个doGet请求以确定要发回的标头的困难。

但是,某些标题的计算可能会带来困难。例如,"内容长度"标题意味着我们需要知道实际资源的大小,因此HEAD可能需要" GET"用于确定相应GET请求的实际大小(以字节为单位)的资源,但它不会给网络带来实际发送资源的负担,尽管它可能已经通过检索资源来加重服务器负担以确定要发送哪些报头返回(即内容长度,内容类型,内容语言等)

答案很长

HTTP specification

  

9.4 HEAD

     

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

     

对HEAD请求的响应可能是可缓存的   响应中包含的信息可用于更新a   以前从该资源缓存的实体。如果是新字段值   表示缓存的实体与当前实体不同(如   将通过内容长度,内容-MD5,ETag或更改来表示   Last-Modified),然后缓存必须将缓存条目视为陈旧。

然而对于GET,它说:

  

9.3 GET

     

GET方法意味着检索任何信息(以。的形式)   entity)由Request-URI标识。如果Request-URI引用   数据生成过程,它是生成的数据   作为响应中的实体而不是源文本返回   过程,除非该文本恰好是过程的输出。

     

GET方法的语义变为"条件GET"如果   请求消息包括If-Modified-Since,If-Unmodified-Since,   If-Match,If-None-Match或If-Range标头字段。有条件的GET   方法请求仅在下传输实体   条件标题字段描述的情况。该   条件GET方法旨在减少不必要的网络使用   通过允许刷新缓存的实体而不需要多个   请求或传输客户已经拥有的数据。

     

GET方法的语义变为"部分GET"如果   请求消息包括Range头字段。部分GET请求   只有部分实体可以转让,如部分所述   14.35。部分GET方法旨在通过允许完成部分检索的实体来减少不必要的网络使用   没有传输客户已经拥有的数据。

     

当且仅当它符合时,对GET请求的响应才是可缓存的   第13节中描述的HTTP缓存要求。

     

有关用于表单的安全注意事项,请参阅第15.1.3节。

如果您read the source code for javax.servlet.http.HttpServlet,您可以看到其文档说明:

  

从受保护的服务方法接收HTTP HEAD请求   处理请求。客户端在需要时发送HEAD请求   只查看响应的标题,例如Content-Type或   内容长度。 HTTP HEAD方法计算输出字节   响应以准确设置Content-Length标头。如果你覆盖   这种方法,你可以避免计算响应体,只需设置   响应标头直接提高性能。确保这一点   你写的doHead方法是安全的和幂等的(也就是说,   保护自己不被多次调用一个HTTP HEAD   请求)。如果HTTP HEAD请求格式不正确,请执行doHead   返回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规范准则,就可以覆盖此行为以提高效率。

答案 1 :(得分:1)

当您想要拦截HTTP GET请求时,使用

doGet()。而

来自DoHead的文档:

  

从受保护的服务方法接收HTTP HEAD请求   处理请求。客户端在需要时发送HEAD请求   只查看响应的标题,例如Content-Type或   内容长度。 HTTP HEAD方法计算输出字节   响应以准确设置Content-Length标头。

     

如果你覆盖   这种方法,你可以避免计算响应体,只需设置   响应标头直接提高性能。确保这一点   你写的doHead方法是安全的和幂等的(也就是说,   保护自己不被多次调用一个HTTP HEAD   请求)。

     

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