普通浏览器 只支持get post方式 ;其他请求方式 如 delelte|put请求是通过 过滤器新加入的支持。
请求方式 | 描述 |
---|---|
GET | 查 |
POST | 增 |
DELETE | 删 |
PUT | 改 |
springmvc实现 :put|post请求方式的步骤
a.在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_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!--上面param-value 当xml 命名为servletname的值-servlet.xml 并且放在web-Inf 目录下可以不用配置 -->
<!--拦截一切请求,给DispatcherServlet 让它自己去找@requestMapping-->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--增加一个HiddenHttpMethodFilter过滤器:目的是给普通浏览器 增加put|delete请求方式-->
<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>
</web-app>
b.表单
i:必须是post方式
ii:通过隐藏域 的value值 设置实际的请求方式 DELETE|PUT
<form action="handler/testPost/1234" method="post">
<input type="submit" value="增">
</form>
<form action="handler/testDelete/1234" method="post">
<!--delete方式需要额外配置-->
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="删">
</form>
<form action="handler/testPut/1234" method="post">
<!--put方式需要额外配置-->
<input type="hidden" name="_method" value="PUT">
<input type="submit" value="改">
</form>
<form action="handler/testGet/1234" method="get">
<input type="submit" value="查">
</form>
c.控制器
@RequestMapping(value = "testPost/{id}",method = RequestMethod.POST)
public String testPost(@PathVariable("id") Integer id){
System.out.println("post:增"+id);
//Service层实现真正的增
return "success";
}
@RequestMapping(value = "testGet/{id}",method = RequestMethod.GET)
public String testGet(@PathVariable("id") Integer id){
System.out.println("get:查"+id);
//Service层实现真正的查
return "success";
}
@RequestMapping(value = "testDelete/{id}",method = RequestMethod.DELETE)
public String testDelete(@PathVariable("id") Integer id){
System.out.println("delete:删"+id);
//Service层实现真正的删
return "success";
}
@RequestMapping(value = "testPut/{id}",method = RequestMethod.PUT)
public String testPut(@PathVariable("id") Integer id){
System.out.println("put:改"+id);
//Service层实现真正的改
return "success";
}
此外,可以发现 ,当映射名相同时@RequestMapping(value="testRest),可以通过method处理不同的请求。
过滤器中 处理put|delete请求的部分源码:
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
HttpServletRequest requestToUse = request;
if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
String paramValue = request.getParameter(this.methodParam);
if (StringUtils.hasLength(paramValue)) {
requestToUse = new HttpMethodRequestWrapper(request, paramValue);
}
}
filterChain.doFilter(requestToUse, response);
}
原始请求:request,改请求默认只支持get post header
但是如果 是"POST" 并且有隐藏域
则,过滤器 将原始的请求 request加入新的请求方式DELETE,并将原始请求 转为 requestToUse 请求(request+Delete请求)
最后将requestToUse 放入 请求链中, 后续再事情request时 实际就使用改造后的 requestToUse