※请求路径相同,根据请求方法确定使用哪个方法来处理请求。
以前实现CRUD(增删改查):
查询:findAll GET
插入:insertUser POST
更新:getUserById GET updateUser PUT
删除:deletUser GET
REST风格实现CRUD(增删改查):
操作 URL 请求方式
查询: /user/1001 GET
插入: /user/ POST
更新: 查询后再修改 /user/ PUT
删除: /user/1001 DELETE
?虽然服务端可以处理PUT和DELETE,但是客户端form表单只有GET和POST两种方式向服务器端发送请求。那么请求方式PUT,DELETE的时候要怎么向服务器端发送请求呢??
思路:客户端都以POST的方式发送请求,同时带过去一个参数_method,然后对请求方式和参数进行判断:
POST&&_method=PUT:PUT
POST&&_method=DELETE:DELETE
POST&&_method=null:POST
上面的处理要在客户端发送请求后DispatcherServelet前处理,这样的处理可以用监听(listener)或过滤器(filter)
web.xml中个组件的顺序:listener>>filter>>servlet
当然spring MVC已经给我们想好了,提供了一个filter:HiddenHttpMethodFilter
源码:
HiddenHttpMethodFilter.java
1 package org.springframework.web.filter; 2 3 import java.io.IOException; 4 import java.util.Locale; 5 import javax.servlet.FilterChain; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletRequest; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletRequestWrapper; 10 import javax.servlet.http.HttpServletResponse; 11 import org.springframework.util.Assert; 12 import org.springframework.util.StringUtils; 13 14 public class HiddenHttpMethodFilter extends OncePerRequestFilter { 15 public static final String DEFAULT_METHOD_PARAM = "_method"; 16 private String methodParam = "_method"; 17 18 public HiddenHttpMethodFilter() { 19 } 20 21 public void setMethodParam(String methodParam) { 22 Assert.hasText(methodParam, "‘methodParam‘ must not be empty"); 23 this.methodParam = methodParam; 24 } 25 26 protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { 27 HttpServletRequest requestToUse = request; 28 if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) { 29 String paramValue = request.getParameter(this.methodParam); 30 if (StringUtils.hasLength(paramValue)) { 31 requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, paramValue); 32 } 33 } 34 35 filterChain.doFilter((ServletRequest)requestToUse, response); 36 } 37 38 private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper { 39 private final String method; 40 41 public HttpMethodRequestWrapper(HttpServletRequest request, String method) { 42 super(request); 43 this.method = method.toUpperCase(Locale.ENGLISH); 44 } 45 46 public String getMethod() { 47 return this.method; 48 } 49 } 50 }
web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" 5 version="4.0"> 6 <filter> 7 <filter-name>HiddenHttpMethodFilter</filter-name> 8 <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> 9 </filter> 10 <filter-mapping> 11 <filter-name>HiddenHttpMethodFilter</filter-name> 12 <url-pattern>/*</url-pattern> 13 </filter-mapping> 14 <servlet> 15 <servlet-name>springMVC</servlet-name> 16 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 17 </servlet> 18 <servlet-mapping> 19 <servlet-name>springMVC</servlet-name> 20 <url-pattern>/</url-pattern> 21 </servlet-mapping> 22 </web-app>
springMVC-servlet.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 6 7 <context:component-scan base-package="com.iwakan.controller"/> 8 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 9 <!-- 10 /WEB-INF下的东西不能直接访问,只能通过转发进行访问。 11 转发和重定向的区别在于,地址发布发生变化,重定向地址发生变化, 12 如果用重定向访问的化话,又相当于直接访问WEB-INF下的页面了 13 --> 14 <property name="prefix" value="/WEB-INF/view/"/> 15 <property name="suffix" value=".jsp"></property> 16 </bean> 17 </beans>
rest.jsp
1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 <html> 3 <head> 4 <title>Rest</title> 5 </head> 6 <body> 7 <a href="/testREST/1001">测试GET</a> 8 <br> 9 <br> 10 <form action="/testREST" method="post"> 11 <input type="submit" value="测试POST"> 12 </form> 13 <br> 14 <form action="/testREST" method="post"> 15 <input type="hidden" name="_method" value="PUT"> 16 <input type="submit" value="测试PUT"> 17 </form> 18 <br> 19 <form action="/testREST/1001" method="post"> 20 <input type="hidden" name="_method" value="DELETE"> 21 <input type="submit" value="测试DELETE"> 22 </form> 23 </body> 24 </html>
RestController.java
1 package com.iwakan.controller; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.web.bind.annotation.PathVariable; 5 import org.springframework.web.bind.annotation.RequestMapping; 6 import org.springframework.web.bind.annotation.RequestMethod; 7 8 @Controller 9 public class RestController { 10 11 @RequestMapping(value = "/testREST/{id}", method = RequestMethod.GET) 12 public String getUserById(@PathVariable("id") Integer id) { 13 System.out.println("GET:id==" + id); 14 return "success"; 15 } 16 17 @RequestMapping(value = "/testREST" ,method = RequestMethod.POST) 18 public String insertUser() { 19 System.out.println("POST"); 20 return "success"; 21 } 22 23 @RequestMapping(value = "/testREST",method = RequestMethod.PUT) 24 public String UpdateUser(){ 25 System.out.println("PUT"); 26 return "success"; 27 } 28 29 @RequestMapping(value = "/testREST/{id}",method = RequestMethod.DELETE) 30 public String deleteUser(@PathVariable("id") Integer id){ 31 System.out.println("DELETE:id=="+id); 32 return "success"; 33 } 34 }
success.jsp
1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 <html> 3 <head> 4 <title>成功</title> 5 </head> 6 <body> 7 <h2>成功</h2> 8 </body> 9 </html>
当点击上面连个按钮时报错:
解决办法:
三种简单处理的办法!
第一:tomcat换到7.0以及以下版本
第二:请求先转给一个Controller,再返回jsp页面
第三种:在你的success页面头部文件将
<%@ page language=”java” contentType=”text/html; charset=UTF-8”
pageEncoding=”UTF-8” isErrorPage=”true”%>
success.jsp
1 <%@ page contentType="text/html;charset=UTF-8" pageEncoding="utf-8" isErrorPage="true" language="java" %> 2 <html> 3 <head> 4 <title>成功</title> 5 </head> 6 <body> 7 <h2>成功</h2> 8 </body> 9 </html>
修改完成后,在点击就成功了。
※ form表单只有GET和POST两种请求,只能通过HiddenHttpMethodFilter来实现。然而,AJax有八种请求方式,所以可以在不通过HiddenHttpMethodFilter直接实现
原文:https://www.cnblogs.com/iwakan/p/13769745.html