HTTP Status 405 - JSPs only permit GET POST or HEAD问题的分析和解决办法

1.出错时的代码

(1)web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
​
    <!-- 配置HiddenHttpMethodFilter:可以把post请求转为DELETE请求和PUT请求 -->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  
    <!-- 配置DispatcherServlet -->
    <!-- 默认的配置文件为 /WEB-INF/<servlet-name>-servlet.xml -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

(2)dispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
​
     <!--自动扫描包中的Controlller -->
    <context:component-scan base-package="com.itheima.controller"/>
    <!-- 配置视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/><!-- 前缀 -->
        <property name="suffix" value=".jsp"/><!-- 后缀,自动拼接 -->
    </bean>
</beans>

(4)Test.java

    @RequestMapping(value = "order", method = RequestMethod.DELETE)
    @ResponseBody()
    public String testOrderDelete(@RequestParam("id") Integer id) {
        System.out.println("删除id为" + id + "的员工");
        return "success";
    }
​
    @RequestMapping(value = "order", method = RequestMethod.PUT)
    @ResponseBody()
    public String testOrderPut(@RequestParam("id") Integer id) {
        System.out.println("更新id为" + id + "的员工");
        return "success";
    }

(5)index.jsp

<form action="order" method="post">
    id:<input type="text" name="id">
    <input type="hidden" name="_method" value="DELETE">
    <input type="submit" value="order提交delete">
</form>
​
<form action="order" method="post">
    id:<input type="text" name="id">
    <input type="hidden" name="_method" value="PUT">
    <input type="submit" value="order提交put">
</form>

2.错误原因分析

当在index.jsp中提交后,HiddenHttpMethodFilter会将method转换成对应的DELETE或PUT,SpingMVC会继续用对应的请求重定向到success.jsp中,而jsp只支持GET、POST、HEAD请求方法。

3.解决方法

(1)为controller里的方法加上@ResponseBody()注解,并且返回一个字符串。不过此方法无法进入指定success.jsp页面。

  @RequestMapping(value = "order", method = RequestMethod.PUT)
    @ResponseBody()
    public String testOrderPut(@RequestParam("id") Integer id) {
        System.out.println("更新id为" + id + "的员工");
        return "success";
    }

(2)使用重定向跳转到指定页面

  @RequestMapping(value = "order", method = RequestMethod.DELETE)
    public String testOrderDelete(@RequestParam("id") Integer id) {
        System.out.println("删除id为" + id + "的员工");
        //无法重定向到WEB-INF目录中,若要访问,需把该页面放入其它路径
        return "redirect:success.jsp";
    }

(3)taocat换到7.0以及以下版本

(4)在你的success页面头部文件设置其页面为错误页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isErrorPage="true"%>

4.HiddenHttpMethodFilter转换请求的源码

   private String methodParam = "_method";
​
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest requestToUse = request;
        if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
            String paramValue = request.getParameter(this.methodParam);
            if (StringUtils.hasLength(paramValue)) {
                String method = paramValue.toUpperCase(Locale.ENGLISH);
                if (ALLOWED_METHODS.contains(method)) {
                    requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
                }
            }
        }
​
        filterChain.doFilter((ServletRequest)requestToUse, response);
    }

猜你喜欢

转载自blog.csdn.net/fy_java1995/article/details/82895875