Spring Boot中JSP表单数据绑定及数据库交互异常排查
我正在开发基于Spring Boot的项目,涉及JSP、Controller、RestController和SQL数据库。当前遇到的问题是:JSP表单的POST请求映射到Controller时,要么获取空值,要么报错。RestController通过REST客户端可正常提交数据,但JSP表单提交后无法将数据存入数据库,也无法在页面展示。
相关代码
JSP表单代码
<h3>To add an Item:</h3> <form action="additem" method="post"> Enter Color name: <input type="text" name="color"><br> Enter Description: <input type="text" name="description"><br> Enter Price: <input type="number" name="price"><br> Enter Shoe Name: <input type="text" name="shoe_name"><br> Enter Size: <input type="text" name="size"><br> Enter User Group: <input type="text" name="user_group"><br> <button>Submit</button> </form>
Controller代码
@RequestMapping(value="/additem", method=RequestMethod.POST) public String insertItem(Model model, @RequestParam(value = "shoe_name") String shoename, ShoeData data) { data = resource.createShoe(shoename, data); model.addAttribute("totalShoes", data); return "warehouse"; }
RestController代码
@RestController public class RestfulResource { @Autowired private ShoeService shoeService; @PostMapping(path = "/{shoename}/shoelist") public ShoeData createShoe(@PathVariable String shoename, @Valid @RequestBody ShoeData data) { ShoeData saveData = shoeService.insertData(data); return saveData; } }
结果展示JSP代码
<c:forEach var="item" items="${totalShoes}"> <tr> <td>${item.id}</td> <td>${item.color}</td> <td>${item.description}</td> <td>${item.price}</td> <td>${item.shoeName}</td> <td>${item.size}</td> <td>${item.userGroup}</td> </tr> </c:forEach>
报错信息
There was an unexpected error (type=Bad Request, status=400).
Validation failed for object='shoeData'. Error count: 1
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'shoeData' on field 'price': rejected value []; codes [typeMismatch.shoeData.price,typeMismatch.price,typeMismatch.int,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [shoeData.price,price]; arguments []; default message [price]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'int' for property 'price'; For input string: ""]
1. 修复表单数据绑定逻辑
JSP表单提交的是application/x-www-form-urlencoded格式数据,而非JSON,需调整实体类和Controller的绑定方式:
(1)调整ShoeData实体类
- 将
price字段从int改为Integer,空值可被处理为null,避免类型转换错误; - 给
shoeName属性添加注解,实现表单蛇形命名(shoe_name)到实体类驼峰命名的自动转换:
public class ShoeData { private Integer price; private String shoeName; @JsonProperty("shoe_name") public String getShoeName() { return shoeName; } @JsonProperty("shoe_name") public void setShoeName(String shoeName) { this.shoeName = shoeName; } // 其他属性的getter/setter方法 }
(2)修改Controller方法
使用@ModelAttribute绑定表单数据到ShoeData(默认可省略,但显式声明更清晰),同时去掉冗余的@RequestParam("shoe_name"),直接从绑定后的实体类中获取值;另外,<c:forEach>需要遍历集合,需将单个实体对象存入集合后再传递到页面:
@Autowired private ShoeService shoeService; @RequestMapping(value="/additem", method=RequestMethod.POST) public String insertItem(Model model, @ModelAttribute ShoeData data) { ShoeData savedData = shoeService.insertData(data); // 将单个对象存入集合,适配页面遍历逻辑 List<ShoeData> shoeList = new ArrayList<>(); shoeList.add(savedData); model.addAttribute("totalShoes", shoeList); return "warehouse"; }
2. 处理表单空值问题
- 给表单的
price字段添加required属性,强制用户输入值:
Enter Price: <input type="number" name="price" required><br>
- 或在实体类中添加校验注解,配合Controller的校验逻辑处理错误:
// 实体类添加注解 public class ShoeData { @NotNull(message = "价格不能为空") @Min(value = 1, message = "价格不能小于1") private Integer price; // 其他属性... } // Controller添加校验处理 @RequestMapping(value="/additem", method=RequestMethod.POST) public String insertItem(Model model, @Valid @ModelAttribute ShoeData data, BindingResult result) { if(result.hasErrors()) { // 校验失败,返回表单页面 return "addItemForm"; // 替换为你的表单页面名称 } ShoeData savedData = shoeService.insertData(data); List<ShoeData> shoeList = new ArrayList<>(); shoeList.add(savedData); model.addAttribute("totalShoes", shoeList); return "warehouse"; }
3. 移除不必要的RestController调用
原Controller通过调用RestController的方式提交数据,属于冗余逻辑,直接注入Service层调用insertData方法即可,避免跨层调用的额外开销。
内容的提问来源于stack exchange,提问作者Vishnu Gautam

