通过 Ajax 发送 PUT、DELETE 请求的两种实现方式
一、普通请求方法发送 PUT 请求
1. 如果不用 ajax 发送 PUT,我们可以通过设置一个隐藏域设置 _method 的值,如下:
<form action="/emps" method="post">
<input type="hidden" name="_method" value="PUT">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit"/>
</form>
2. 控制层:
@RequestMapping(value="/emps", method=RequestMethod.PUT)
public String updateEmp(Employee employee) {
System.out.println(employee);
return "redirect:success.jsp";
}
注意:这里如果采用请求转发的方式即 return "success.jsp",将会出现以下问题:(Tomcat 7.0 版本不会出现这个问题)
SpringMVC HTTP Status 405 - JSPs only permit GET POST or HEAD
采用重定向的方式可以避免这个问题。
3. 这种方式发送 PUT 请求,还需在 web.xml 中配置一个 HiddenHttpMethodFilter 过滤器(如果使用Spring Boot 则会自动配置)
<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>
浏览器 form 表单只支持 GET 与 POST 请求,而DELETE、PUT 等 method 并不支持,Spring3.0 添加了一个过滤器,可以将这些请求转换为标准的 http 方法,使得支持 GET、POST、PUT 与 DELETE 请求。
首先看到 HiddenHttpMethodFilter 过滤器的源码:


二、通过 ajax 发送 DELETE 请求(需要带_method参数)
/* 删除员工 */
function deleteEmp(empId){
$.ajax({
url : "emps",
data : {_method : "DELETE", empId : empId},
type : "POST",
success : function(result){ }
})
}
发送表单 ajax 请求:
$("#updateBtn").click(function(){
$.ajax({
url : "emps",
data : $("#updateEmpFormNode").serialize()+"&_method=put",
type : "post",
success : function(result){
alert(result);
}
})
})
三、直接指定 ajax 请求中的 type 为 put/delete(不带 _method 参数)
1. 把上述第二点的表单更新改写为如下:
$("#updateBtn").click(function(){
$.ajax({
url : "emps",
data : $("#updateEmpFormNode").serialize(),
type : "PUT",
success : function(result){
alert(result);
}
})
})
出错:

这问题是由于 Tomcat 本身引起的,导致这个问题是因为 SpringMVC 绑定 POJO 对象时获取不到数据,然后执行更新语句时 sql 语句出错导致的。由于 POJO 的数据都为空,所以被执行的更新语句可能会为 update emp set where empId = ?,反正被执行更新语句肯定是有错的。想要知道为什么获取不到数据,下面首先先了解一下 Tomcat 如何封装数据以及SpringMVC如何绑定数据
① Tomcat 首先会将请求体中的数据,封装一个map。
② request.getParameter("empName") 就会从这个map中取值。
③ SpringMVC封装POJO对象的时候,通过 request.getParamter("empName"); 获取一个字段的值,然后赋值到 POJO 中属性名为 empName 的属性。如:
String temp = (String)request.getParamter("empName");
Employee emp = new Employee();
emp.setEmpName(temp);
查找到 protected void parseParameters() 该方法
protected String parseBodyMethods = "POST";
if( !getConnector().isParseBodyMethod(getMethod()) ) {
success = true;
return;
}
当 Tomcat 知道是请求不是 POST 请求时,会直接 return,而不会继续往下执行解析封装参数,所以当 request.getParamter("empName") 从 map 取数据时,由于 empName 参数没有被封装到 map 中,getParmater获取到值为 null。
2.1 在 web.xml 配置上HttpPutFormContentFilter;
<filter>
<filter-name>HttpPutFormContentFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.2 HttpPutFormContentFilter 的作用;将请求体中的数据解析包装成一个map。
2.3 request被重新包装,request.getParameter()被重写,就会从自己封装的map中取数据
四,仍然使用PUT DELETE 请求:传递参数的时候data需要设置为json字符串
1.仍然使用put和delete请求,直接指定 ajax 请求中的 type 为 put/delete(不带 _method 参数),并且需要传递参数的时候data需要设置为json字符串。(SpringBoot环境中不需要配置任何东西,其他未知)
var jsonstr = {"id":1,"name":"zsw"};
$.ajax({
url:"/update",
type:"PUT",
contentType:"application/json",//设置请求参数类型为json字符串
data:JSON.stringify(jsonstr),//将json对象转换成json字符串发送
dataType:"json",
success:function(result){
alert(result);
},
});
客户端需要使用@RequestBody标注
@RequestMapping(value = "update",method = RequestMethod.PUT)
public String update(@RequestBody Book book){
System.out.println(book);
return BookClient.update(book);
}
我现在正在用的
//不能传表单序列化数据
var jsonstr = {"id":8,"projectName":"z"};
$.ajax({
url:"/project/update",
type:"PUT",
contentType:"application/json",//设置请求参数类型为json字符串
data:JSON.stringify(jsonstr),//将json对象转换成json字符串发送
dataType:"json",
success:function(result){
alert(result);
},
}); //对应的controller
@RequestMapping(value = "update",method = RequestMethod.PUT)
public Result updateProjectById(@RequestBody Project project){
var data=$("#updateForm").serialize();
console.log(data);
$.ajax({
url:"/project/update",
type:"POST",
data : $("#updateForm").serialize()+"&_method=put",
// data:{_method:"PUT"},
success:function(result){
alert("修改成功");
}
})
//对应的controller
@RequestMapping(value = "update",method = RequestMethod.PUT)
public Result updateProjectById(Project project){
拓展:
Ajax请求($.ajax()为例)中data属性传参数的形式
参考链接:
https://blog.csdn.net/Mrs_Yu/article/details/92376069
https://blog.csdn.net/liuyuanjiang109/article/details/78972644
通过 Ajax 发送 PUT、DELETE 请求的两种实现方式的更多相关文章
- iOS- 网络请求的两种常用方式【GET & POST】的区别
GET和POST 网络请求的两种常用方式的实现[GET & POST] –GET的语义是获取指定URL上的资源 –将数据按照variable=value的形式,添加到action所指向的URL ...
- Ajax发送PUT/DELETE请求时出现错误的原因及解决方案
本文讲什么? 大家应该都知道.在HTTP中,规定了很多种请求方式,包括POST,PUT,GET,DELETE等.每一种方式都有这种方式的独特的用处,根据英文名称,我们能够很清楚的知道DELETE方法的 ...
- java发送http get请求的两种方式
长话短说,废话不说 一.第一种方式,通过HttpClient方式,代码如下: public static String httpGet(String url, String charset) thro ...
- kotlin for android----------MVP模式下(OKHttp和 Retrofit+RxJava)网络请求的两种实现方式
今天要说的干货是:以Kotlin,在MVP模式下(OKHttp和 Retrofit+RxJava)网络请求两种实现方式的一个小案例,希望对大家有所帮助,效果图: Retrofit是Square公司开发 ...
- php笔记04:get/post请求有两种主要方式
get/post的区别有哪些? 1. 安全性get请求的数据会显示在地址栏上,post请求的数据,放在http协议的消息体中 2. 从可以提交的数据大小来看: http协议本身并没有限制数据大 ...
- android 定时请求(两种实现方式)
方式一: Handler + Runnable (借鉴网址:http://stackoverflow.com/questions/6207362/how-to-run-an-async-task-fo ...
- Ajax中的get和post两种请求方式的异同
Ajax中我们经常用到get和post请求.那么什么时候用get请求,什么时候用post方式请求呢? 在做回答前我们首先要了解get和post的区别. 1. get是把参数数据队列加到提交表单的A ...
- C#中Post请求的两种方式发送参数链和Body的
POST请求 有两种方式 一种是组装key=value这种参数对的方式 一种是直接把一个字符串发送过去 作为body的方式 我们在postman中可以看到 sfdsafd sdfsdfds publi ...
- .net中对HTTP请求的两种请求:Get和Post的操作
.net中对HTTP请求的简单操作总结 第一部分,HTTP协议的简单了解 一. 什么是HTTP协议 超文本传输协议 (HTTP-Hypertext transfer protoco ...
随机推荐
- Python基础(使用模块)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- ' a test module ' __author__ = 'Michael Liao' import ...
- 深入理解Spring IOC源码分析
Spring容器初始化 本文使用的是Spring 5.1.7版本 写在前面:我们看源码一般有3种方式. 第一种直接用class文件,IDEA会帮我们反编译成看得懂的java代码 第二种是用maven的 ...
- 1组-Alpha冲刺-1/6
一.基本情况 队名:震震带着六菜鸟 组长博客:https://www.cnblogs.com/Klein-Wang/p/15526531.html 小组人数:7人 二.冲刺概况汇报 王业震 过去两天完 ...
- inux 下配置网卡的别名即网卡子IP的配置 转
what 什么是ip别名?用windows的话说,就是为一个网卡配置多个ip.when 什么场合增加ip别名能派上用场?布网需要.多ip访问测试.特定软件对多ip的需要...and so on. ho ...
- 美团饿了么领取外卖优惠券微信小程序的开发及上线_怎样点外卖省钱_外卖小程序的开发及上线
都1202年了,估计没人不知道外卖了,那么就有两种人在思考两种问题: 普通人:怎么点外卖划算? 程序员:怎么通过外卖赚钱? 话不多说,为了让你们相信我有能力来讲这块内容,先给你们看一个很简单的小程序: ...
- Java设计模式之(八)——适配器模式
1.什么是适配器模式? Convert the interface of a class into another interface clients expect.Adapter lets clas ...
- idea 的git代码回退回某个版本
intellij idea 的git代码回退回滚 找到Reset HEAD 填写提交码,注意这里要选择"hard" 使用命令行强制提交代码 git push -f
- layui某个字段不让页面显示显示
<script src="/layuiadmin/layui/layui.js"></script> <script> layui.config ...
- IPv4 寻址方式简介
IPv4 支持三种不同类型的寻址模式.单播寻址方式.广播寻址方式和组播寻址方式.本章节我们来介绍这些寻址方式. 单播寻址方式 在这种模式下,数据只发送到一个目标主机.Destination Addre ...
- 最简单的Python3启动浏览器代码
#encoding=utf-8 from selenium import webdriver import time from time import sleep dr = webdriver.F ...