You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 19:05:19