Thymeleaf中DTO传递枚举值为Null及下拉框默认值问题求助
问题与解决方案
问题描述
- 修改用户类型时,数据库中
usertype字段被设置为Null - 下拉选择框无法默认选中用户当前的
Usertype,尝试th:selected="${u.usertyp}"和if语句均无效
相关代码:
Controller
@PostMapping("editUser/{userId}") public String editUser(@ModelAttribute("sessionUser") User sessionUser, @Valid @ModelAttribute("userDTO") UserDTO userDTO, @PathVariable Long userId, Model model){ if(sessionUser==null || sessionUser.getUsertyp() == Usertyp.USER) { return "redirect:/"; } else { User changedUser = userService.findById(userId); changedUser.setUsertyp(Usertyp.fromString(userDTO.getUsertyp())); userService.save(changedUser); return "redirect:/administration"; } }
DTO
public class UserDTO { //TODO usertyp anpassem private String usertyp; public UserDTO(String usertyp) { this.usertyp = usertyp; } public String getUsertyp() { return usertyp; } public void setUsertyp(String usertyp) { this.usertyp = usertyp; } }
Template
<ul class="list-group list-group-flush"> <span th:each="u : ${userList}"> <li class="list-group-item"> <span th:text="${u.username}"></span> <form th:object="${userDTO}" th:action="@{/editUser/{userId}(userId=${u.id})}" method="Post" id="Rolle"> <select th:field="*{usertyp}" form="Rolle"> <option th:each="usertyp : ${T(com.example.myproject.entities.Usertyp).values()}" th:text="${usertyp.displayText}" th:value="${usertyp.displayText}"> </option> </select> <input class="btn btn-primary" type="submit" value="Speichern"> </form> </li> </span> </ul>
解决方案
1. 解决数据库usertype为Null的问题
- 添加DTO无参构造函数:Spring MVC实例化DTO时默认调用无参构造,当前DTO只有带参构造,导致无法正确绑定表单参数,
userDTO.getUsertyp()返回Null。修改DTO:
public class UserDTO { private String usertyp; // 添加无参构造 public UserDTO() {} public UserDTO(String usertyp) { this.usertyp = usertyp; } public String getUsertyp() { return usertyp; } public void setUsertyp(String usertyp) { this.usertyp = usertyp; } }
- 校验
Usertyp.fromString方法:确保该方法能正确解析表单提交的displayText值(比如大小写匹配、字符串完全一致)。如果displayText和枚举的name不一致,需要保证fromString逻辑能正确映射,例如:
public static Usertyp fromString(String displayText) { for (Usertyp type : Usertyp.values()) { if (type.getDisplayText().equals(displayText)) { return type; } } // 处理无效值,避免返回Null throw new IllegalArgumentException("Invalid user type: " + displayText); }
2. 解决下拉框默认选中当前用户类型的问题
Thymeleaf的th:field会自动处理选中状态,但当前模板中所有表单共用同一个userDTO模型,无法为每个用户单独设置默认值。可以通过以下方式解决:
修改select标签,移除th:field,手动添加th:selected判断当前枚举是否等于用户的usertyp:
<select name="usertyp" form="Rolle"> <option th:each="usertyp : ${T(com.example.myproject.entities.Usertyp).values()}" th:text="${usertyp.displayText}" th:value="${usertyp.displayText}" th:selected="${usertyp == u.usertyp}"> </option> </select>
此时表单提交的参数会自动绑定到userDTO.usertyp,因为name属性和DTO字段名一致,同时能正确默认选中用户当前的类型。
内容的提问来源于stack exchange,提问作者id0n7g3tit
相关产品推荐
相关产品推荐

