【问题标题】:HTTP Status 405 - JSPs only permit GET POST or HEADHTTP 状态 405 - JSP 只允许 GET POST 或 HEAD
【发布时间】:2014-07-16 05:16:47
【问题描述】:

自 JSP 2.3 (Tomcat 8) 起,仅支持 JSP 的方法是 GET POST 或 HEAD:

https://jcp.org/aboutJava/communityprocess/maintenance/jsr245/245-MR3.html http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/servlet/JspServlet.java?view=diff&r1=1497877&r2=1497878&pathrev=1497878

但是,我想,这是一个很大的不兼容更改,例如,对于异常处理程序,它用于转发到 JSP 以呈现异常和 iso JSP 视图,因为 JSP 2.3 响应是:

Method Not Allowed
HTTP Status 405 - JSPs only permit GET POST or HEAD 

description The specified HTTP method is not allowed for the requested resource.
Apache Tomcat/8.0.3

如果我们在异常情况下使用 REST 和 Spring HandlerExceptionResolver,我们肯定会遇到这个问题。这个问题有解决办法吗(iso更改http方法类型)?

【问题讨论】:

    标签: jsp tomcat exception-handling tomcat8


    【解决方案1】:

    抱歉,(目前)没有解决方法。我对 EG 的建议是处理的方法是可配置的。那个建议被拒绝了。我建议您向他们提出这个特定问题,因为这是一个很好的论据,可以让支持的方法在每个 JSP(或 JSP 组)的基础上进行配置。

    同时,我将在您为此提出的错误下使用某种形式的 Tomcat 特定配置来看看使其可配置:https://issues.apache.org/bugzilla/show_bug.cgi?id=56568

    更新:从 Tomcat 8.0.9 开始,当使用 JSP 生成错误页面时,将允许任何 HTTP 方法。

    【讨论】:

    • 此更改是何时进行的? jsps 的 PUT 请求被拒绝了多长时间?
    • JSP 2.3 规范要求 JSP 只响应 GET、HEAD 和 POST。所有其他 HTTP 方法的行为未定义。 Tomcat 选择拒绝它们以防止 HTTP 动词篡改攻击。由于这是 JSP 2.3,因此更改适用于 Tomcat 8 及更高版本。
    • 如何指定 JSP 错误页面以重定向工作?我正在使用 Tomcat 8.0.9
    • 如果您重定向到错误页面(而不是使用错误处理机制),您需要设置 isErrorPage="true" 并等待 8.0.12 发布。
    【解决方案2】:

    正如@MarkThomas 所指出的,如果您像这样将您的JSP 页面声明为errorPage,则可以发出任何HTTP 请求

    如果您不想这样做,那么还有另一种选择
    1.创建过滤器(如果你直接要调用JSP页面)或者创建servlet(最终会调用JSP页面)
    2. 在 doFilter() 或 servlet doPut()/doDelete() 中执行此操作

    在这里,我在过滤器中执行此操作,其中 requestServletRequest 对象。
    我正在使用HttpRequestWrapper 用虚假请求包装原始请求,并告诉它为DELETEPUT 请求返回POST,因此JSP 认为它是POST 请求和该页面已执行,唯一的缺点是您将无法分辨原始请求是什么;如果您设置具有原始方法名称的属性,也可以涵盖这一点,就像这样

    HttpServletRequest req = (HttpServletRequest) request;
    request.setAttribute("method", req.getMethod());
    req.getRequestDispatcher("/WEB-INF/resources/" +  resourceName + ".jsp").forward(new HttpServletRequestWrapper(req) {
        @Override
        public String getMethod() {
            String method = super.getMethod();
            if (method.equalsIgnoreCase("delete") || method.equalsIgnoreCase("put")) {
                return "POST";
            } else {
                return method;
            }
        }
    }, response);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-12
      • 2014-06-22
      • 2017-06-15
      • 2018-12-20
      • 2021-06-04
      • 2021-09-19
      • 1970-01-01
      • 2018-10-14
      相关资源
      最近更新 更多