JavaScript Ajax实现表单式PUT请求:Spring Boot后端接收值为空
问题描述
想用PUT方法实现数据更新,但HTML表单不支持PUT请求,于是尝试用JavaScript Ajax模拟表单提交。最初用Map存储表单键值对,没能生成正确的键值结构;改用FormData转换为JSON发送PUT请求后,前端能生成正确的JSON数据(示例:{"id":"1","code":"sfasdfas","name":"fdsafsdf","type":"RURAL"}),但后端Spring Boot中通过@ModelAttribute注解绑定的Location对象所有属性均为空,需要解决这个问题。
初始前端代码
function updateRecord(divId) { var map = new Map(); var hiddenField; var divNode = document.getElementById(divId); var inputNodes = divNode.getElementsByTagName('INPUT'); for(var i = 0; i < inputNodes.length; ++i) { var inputNode1 = inputNodes[i]; var inputVale = inputNode1.value; var inputName = inputNode1.name; map.set = (inputName,inputVale); } let contextURL = 'http://localhost:8080/LocationWeb/LocCon/updateLocationValues/'; let parmURL = contextURL + map; var xhr = new XMLHttpRequest(); xhr.open("PUT", parmURL, true); xhr.send(); xhr.onload = function() { if (xhr.status != 200) { console.log('ERROR'); } else { listAllPageCall(); } }; xhr.onerror = function() { window.location = 'http://localhost:8080/LocationWeb/LocCon/listAllLocations'; }; }
更新后前端代码
function updateRecord(divId) { var form = document.getElementById('updateTable'); var xhr = new XMLHttpRequest(); var formData = new FormData(form); //open the request xhr.open('PUT','http://localhost:8080/LocationWeb/LocCon/updateLocationValues') xhr.setRequestHeader("Content-Type", "application/json"); var sendJs0n = JSON.stringify(Object.fromEntries(formData)); //send the form data xhr.send(sendJs0n); //This acts a body message form.onsubmit = function(event) { xhr.onreadystatechange = function() { if (xhr.readyState == XMLHttpRequest.DONE) { form.reset(); //reset form after AJAX success or do something else } } //Fail the onsubmit to avoid page refresh. return false; } }
后端Spring Boot代码
@PutMapping("/updateLocationValues") public String updateLocationValues(@ModelAttribute("location") Location location, ModelMap resModMap) { locationService.updateLocation(location); List<Location> allLocations = locationService.getAllLocation(); resModMap.addAttribute("allLocations", allLocations); return "displayAllLocations"; }
解决方案
1. 修改后端接收注解
@ModelAttribute用于解析**表单格式(application/x-www-form-urlencoded)**的请求参数,而你当前前端发送的是JSON格式(Content-Type为application/json)的请求体,需要改用@RequestBody注解来绑定JSON数据:
@PutMapping("/updateLocationValues") public String updateLocationValues(@RequestBody Location location, ModelMap resModMap) { locationService.updateLocation(location); List<Location> allLocations = locationService.getAllLocation(); resModMap.addAttribute("allLocations", allLocations); return "displayAllLocations"; }
2. 确保Location类符合要求
- 类的属性名要和JSON中的键名完全匹配(比如JSON里的
id对应类的id属性) - 所有属性必须有对应的getter和setter方法,Spring需要通过这些方法完成属性赋值
- 如果属性名和JSON键名不一致,可以用
@JsonProperty注解映射,比如:public class Location { @JsonProperty("id") private Long locationId; // getter、setter... }
3. 调整前端代码逻辑
当前前端代码中form.onsubmit的绑定时机有问题,可能导致请求发送逻辑混乱,建议修改为:
function updateRecord(divId) { var form = document.getElementById('updateTable'); // 阻止表单默认提交行为 form.addEventListener('submit', function(event) { event.preventDefault(); var xhr = new XMLHttpRequest(); var formData = new FormData(form); xhr.open('PUT','http://localhost:8080/LocationWeb/LocCon/updateLocationValues'); xhr.setRequestHeader("Content-Type", "application/json"); var sendJson = JSON.stringify(Object.fromEntries(formData)); xhr.onreadystatechange = function() { if (xhr.readyState == XMLHttpRequest.DONE) { if(xhr.status === 200) { form.reset(); listAllPageCall(); } else { console.log('ERROR'); } } }; xhr.onerror = function() { window.location = 'http://localhost:8080/LocationWeb/LocCon/listAllLocations'; }; xhr.send(sendJson); }); }
内容的提问来源于stack exchange,提问作者S14321K
相关产品推荐
相关产品推荐

