簡體   English   中英

tomcat將404狀態改成403進行http刪除

[英]tomcat changes 404 status into 403 for http delete

我有一個奇怪的問題,如果我的 servlet 發送 200 ok http 狀態,它會按預期工作,並且客戶端按預期獲得 200 狀態。 但是,如果我的 servlet 返回 404 狀態,tomcat 似乎會將其更改為 403 狀態。 如果我使用 http get方法,則不會發生這種情況。 我還沒有測試putpost

我想非常清楚地說明我的 servlet 的doDelete方法執行得很好。 只是返回給瀏覽器的狀態碼發生了變化。

我將提供一個最小的測試用例來演示這個問題。

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/api/test403/*")
public class Test403 extends HttpServlet {
    public void doDelete(HttpServletRequest request, HttpServletResponse response) {
        try {
            String p = request.getParameter("send404");
            if (p != null && "1".equals(p)) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "not found.");
            } else {
                response.sendError(HttpServletResponse.SC_OK, "ok.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static final long serialVersionUID = 1L;
}

然后我通過以下網址進行測試

myproject/api/test403?send404=1
myproject/api/test403?send404=0

什么可能導致這種行為? 我不太熟悉整個 servlet/容器架構。 我只在 1 台使用 tomcat 7.0.41 的服務器上遇到這個問題。 我嘗試了另一台服務器,它沒有表現出這種行為。

編輯 - 根據請求,這里是 chrome 網絡面板的一些輸出。 我使用 ajax 來發起這個特定的請求:

Request Headers

DELETE /xxxxx HTTP/1.1
Host: xxxxx
Connection: keep-alive
Origin: xxx
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */*
Referer: xxx
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: xxx

Response Headers

HTTP/1.1 403 Forbidden
Server: Apache-Coyote/1.1
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Content-Encoding: gzip
Vary: Accept-Encoding
Date: Wed, 16 Apr 2014 02:30:32 GMT

我沒有刪除任何標題,盡管我匿名了一些值。

組合...

  • 一個 http DELETE請求
  • 調用HttpServletResponse.sendError(status, message)從您的 servlet doDelete()方法發送 404
  • 配置自定義 404 錯誤處理程序頁面(例如,通過web.xml<error-page>指令)
  • 為您的上下文保留readonly = true的默認值

將導致客戶端收到 403 狀態而不是您發送的 404 狀態。

對 servlet 的請求可以在不需要readonly為 false 的情況下為 http 刪除請求提供服務,但對文件的請求不能。 發生的情況是,當您調用sendError() ,tomcat 將嘗試查找與您指定的任何 http 狀態匹配的自定義錯誤頁面。 在這種情況下,它找到了一個( /my404.html ),因此為了處理它,它基本上重新啟動了整個請求路由/調度過程,包括對請求運行所有過濾器。 但是,這一次,由於它是一個靜態文件請求,它遇到了一個內置過濾器,該過濾器會查找 http 的DELETE方法,然后檢查readonly = false 如果不是,則請求被拒絕,並將響應狀態更改為 403 forbidden 因為您不允許刪除名為/my404.html的靜態文件。

一個明智的解決方法是使用HttpServletResponse.setStatus(status)而不是HttpServletResponse.sendError(status, message) ,這樣 tomcat 就不會嘗試查找錯誤頁面。 正如@BogdanZurac 所提到的,除了設置狀態以防止它尋找自定義錯誤頁面之外,您可能還需要發送一個簡短的響應正文(即“oops Error 404”)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM