SpringMVC表单字段与Java Bean属性不一致时的参数绑定疑问
SpringMVC参数绑定疑问解答
相关代码示例
Kotlin版User数据类
@NoArg data class User( var username: String, var password: String, // ... )
Java版Bean与Controller
// bean public class User { private int id; private String firstname; private String lastname; private String username; private String password; private String email; // ... @Override public String toString() { return "User{" + "id=" + id + ", firstname='" + firstname + '\'' + ", lastname='" + lastname + '\'' + ", username='" + username + '\'' + ", password='" + password + '\'' + ", email='" + email + '\'' + '}'; } } // controller @Controller public class UserController { @PostMapping("/user") public String getUser(User user){ System.out.println(user); return "success"; } }
HTML表单
<form th:action="@{/user}" method="post"> username: <label> <input type="text" name="userName"> </label> password: <label> <input type="password" name="passWord"> </label> <!-- .... --> <input type="submit" value="submit"> </form>
运行输出结果
User{username=a, password=a}
疑问
通常我们知道,SpringMVC要正常完成参数绑定,需要表单的name字段和Java Bean的属性名一致。但上面的例子里,表单字段是userName、passWord,而Java Bean的属性是username、password,明明名字不一致,为什么代码还能正常运行?
解答
这是因为SpringMVC默认的属性命名策略在起作用。
SpringMVC的DataBinder默认用BeanWrapperImpl处理属性绑定,而BeanWrapperImpl支持驼峰命名与纯小写属性名的自动转换——当处理userName这类请求参数时,它会自动适配到username这种标准属性名。
具体逻辑是:BeanWrapper会对请求参数名进行格式转换,比如把userName的大小写分隔去掉,转为全小写的username,再去匹配Bean的属性;同时也支持反向转换。只要参数名和属性名的语义一致,就能完成绑定。
如果需要关闭这种自动适配,可以通过@InitBinder自定义WebDataBinder的命名策略,设置严格的匹配规则,但默认情况下这个自动转换是开启的。
内容的提问来源于stack exchange,提问作者ITGuoKe
相关产品推荐
相关产品推荐

