doGet 和 doHead 方法之间的区别

HEAD 只发回与相应 GET 请求相同的header信息,但没有实体主体。 GET 将发送相同的标头和实体主体。当然,在特殊情况下,GET 不会在其body中发回任何内容,那么 GET 和 HEAD 的行为类似。

《HTTP The Definitive Guide 》的说法

doHead允许客户端检查资源的header,而无需实际获取资源。使用 HEAD可以:

  1. 在不获取资源的情况下找出资源(例如,确定其类型)。
  2. 通过查看响应的状态代码来查看对象是否存在。
  3. 通过查看header来测试资源是否已被修改。

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

因此,doHead 是否调用 doGet 可能只是一个实现细节,但如果是这样,doHead 需要在发送响应之前剥离 doGet 的body。不过,这种实现效率很低,因为理想情况下,doHead 不应在执行整个 doGet 请求来确定要发回哪些header。
不过,某些header的计算可能会带来困难。例如,“Content-Length”标头意味着我们需要知道实际资源的大小,因此 HEAD 可能需要“GET”资源来确定相应 GET 请求的实际大小(以字节为单位),但这不会造成负担网络实际发送回资源​​,尽管它可能会给服务器带来资源检索的负担,以确定发送回哪些标头(即内容长度、内容类型、内容语言等)

HttpServlet 里面的源码
    /**
     *
     *
     * <p>
     * Receives an HTTP HEAD request from the protected <code>service</code> method and handles the request. The client
     * sends a HEAD request when it wants to see only the headers of a response, such as Content-Type or Content-Length. The
     * HTTP HEAD method counts the output bytes in the response to set the Content-Length header accurately.
     *
     * <p>
     * If you override this method, you can avoid computing the response body and just set the response headers directly to
     * improve performance. Make sure that the <code>doHead</code> method you write is both safe and idempotent (that is,
     * protects itself from being called multiple times for one HTTP HEAD request).
     *
     * <p>
     * The default implementation calls {@link #doGet(HttpServletRequest, HttpServletResponse)}. If the
     * {@link ServletConfig} init parameter {@link #LEGACY_DO_HEAD} is set to "TRUE", then the response instance is wrapped
     * so that the response body is discarded.
     *
     * <p>
     * If the HTTP HEAD request is incorrectly formatted, <code>doHead</code> returns an HTTP "Bad Request" message.
     *
     * @param req the request object that is passed to the servlet
     *
     * @param resp the response object that the servlet uses to return the headers to the clien
     *
     * @throws IOException if an input or output error occurs
     *
     * @throws ServletException if the request for the HEAD could not be handled
     */
    protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        if (legacyHeadHandling) {
            NoBodyResponse response = new NoBodyResponse(resp);
            doGet(req, response);
            response.setContentLength();
        } else {
            doGet(req, resp);
        }
    }

通过阅读 NoBodyResponse 的代码,会发现它只是一个响应,其输出流丢弃所有数据,并且仅计算字节数以确定相应 GET 响应的正确内容长度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值