HTTP状态码405 - 仅允许使用GET、POST或HEAD方法访问JSP页面。

19

自从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 进行异常渲染,因为自 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,那么我们肯定会遇到这个问题。有没有解决这个问题的方法(即更改http请求方法类型)?

2个回答

4
抱歉,目前没有解决此问题的方法。我的建议是将处理方法设置为可配置。但该建议被拒绝。建议您就此问题与他们进行讨论,因为这是支持按每个JSP(或一组JSP)基础进行配置的好理由。
同时,我将尝试使用某种Tomcat特定的配置方式来使其可配置,并在您提出的错误下进行修复:https://issues.apache.org/bugzilla/show_bug.cgi?id=56568 更新:自Tomcat 8.0.9起,使用JSP生成错误页面时,任何HTTP方法都将被允许。

这个更改是什么时候进行的?JSP的PUT请求被拒绝多长时间了? - one stevy boi
1
JSP 2.3规范要求JSP仅响应GET、HEAD和POST请求。所有其他HTTP方法的行为未定义。Tomcat选择拒绝它们以防止HTTP动词篡改攻击。由于这是JSP 2.3,因此更改适用于Tomcat 8及以上版本。 - Mark Thomas
如何指定JSP错误页面以便重定向工作? 我正在使用Tomcat 8.0.9。 - Grigory Kislin
1
如果您重定向到错误页面(而不是使用错误处理机制),则需要设置isErrorPage =“true”,并等待8.0.12发布。 - Mark Thomas

3
如@MarkThomas所指出的,如果您将JSP页面声明为errorPage,则可以进行任何HTTP请求。
enter image description here
如果不想这样做,则还有一个选择:
1.创建一个过滤器(如果您想直接调用JSP页面),或者创建一个Servlet(最终将调用JSP页面)。
2.在doFilter()中进行此操作,或者在servlet的case下进行doPut()/doDelete()。
enter image description here
在这里,我使用过滤器来实现此操作,其中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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接