SpringBoot-Thymeleaf单选框默认值无法传递至控制器问题排查
SpringBoot-Thymeleaf默认单选框值无法传递至控制器问题解决
问题描述
页面加载时需将默认选中的单选框值发送至控制器,以此查询数据库并填充多选下拉框,但控制器中获取到的单选框值始终为null。
相关代码
HTML代码
<form id="form1" action="#" th:action="@{/dbAssigned}" method="post" th:object="${formAssigned}"> <th:block th:insert="~{fragments/mainMenu}"></th:block> <div class="page"> <div class="main" style="width:940px;min-height:530px"> <div style="clear:both;width:98%;margin-left:10px;"> <h4>Database Assets and Users</h4> <div class="wizpanel1" style="min-height:16px;"> <span id="MainContent_lblMessage" class="message"></span> </div> <div class="dbxleft_"> <div id="divAvailOrg" class="dbxll_"> <div id="divAvailTitle" class="dbxtitle_ ui-buttonset"> <table id="MainContent_rblAvailable" class="rbl"> <tbody> <tr> <td> <input id="mainContent_rblAvailable_0" type="radio" th:field="*{mainContent}" value="1" checked="checked" class="ui-helper-hidden-accessible"> <label for="MainContent_rblAvailable_0" class="ui-state-active ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left ui-state-hover" role="button" aria-disabled="false"> <span class="ui-button-text">Organizations</span></label> </td> <td> <input id="mainContent_rblAvailable_1" type="radio" th:field="*{mainContent}" value="2" class="ui-helper-hidden-accessible"><label for="MainContent_rblAvailable_1" class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-right" role="button" aria-disabled="false"><span class="ui-button-text">Users</span></label> </td> </tr> </tbody> </table> </div> <div id="divCntTitle" class="dbxtitleC_"> <h6 id="MainContent_h6UNO">75 Items</h6> </div> <div id="div3" class="dbxlbx"> <select size="23" name="ctl00MainContentlbxAvail" onchange="javascript:setTimeout('', 0)" id="MainContent_lbxAvail" style="font-size:13px;width:100%;"> <option value="18" title="Abbott"></option> <option value="270" title="AbbVie"></option> </select> </div> <span style="width:50%;float:left;padding-top:5px;"> <a id="MainContent_lkbClearFilters" href="javascript:('','')">Clear Selection</a> </span> </div> </div> <div class="dbxright_"> <div id="div4" class="dbxtitler_"> <h6 id="MainContent_h6DBLabel">Treatment Pathways Databases, 114 Items</h6> </div> <div class="wizpanel2txp_" style="margin-bottom:20px;"> <span class="wizanswertxp_"> <select id="MainContent_lbxDBList" size="23" onchange="javascript:setTimeout()" name="MainContent" style="font-size:13px;width:100%;" multiple> <option value="1000760" title="123"></option> <option value="1000776" title="456"></option> <option value="1000803" title="789"></option> </select> </span> </div> </div> </div> </div> <div class="clear"> </div> </div> </form>
Controller代码
@RequestMapping(value = "/dbAssigned") public Object lkbDbAssigned_Click(@ModelAttribute("formAssigned") FormAssigned formAssigned, Model model) { System.out.println("Radio Value:"+formAssigned.getMainContent()); FormAssigned assigned = new FormAssigned(); model.addAttribute("formAssigned",assigned); return "dbAssigned"; }
Form Model代码
public class FormAssigned { private String mainContent; public String getMainContent() { return mainContent; } public void setMainContent(String mainContent) { this.mainContent = mainContent; } }
解决方案
1. 拆分请求方法并初始化模型默认值
将控制器方法拆分为GET(页面初始化)和POST(表单提交)两个方法,在GET方法中为表单模型设置默认单选框值,确保Thymeleaf能正确绑定默认选中状态:
// 页面初始化GET请求 @RequestMapping(value = "/dbAssigned", method = RequestMethod.GET) public String initDbAssignedPage(Model model) { FormAssigned assigned = new FormAssigned(); // 设置默认选中的单选框值为"1"(对应Organizations选项) assigned.setMainContent("1"); model.addAttribute("formAssigned", assigned); // 此处可根据默认值查询数据库,预先填充多选下拉框数据 // List<Database> dbList = databaseService.getDatabasesByType(assigned.getMainContent()); // model.addAttribute("dbList", dbList); return "dbAssigned"; } // 表单提交POST请求 @RequestMapping(value = "/dbAssigned", method = RequestMethod.POST) public String handleDbAssignedSubmit(@ModelAttribute("formAssigned") FormAssigned formAssigned, Model model) { System.out.println("Radio Value:" + formAssigned.getMainContent()); // 根据选中的单选框值查询数据库,更新多选下拉框数据 // List<Database> dbList = databaseService.getDatabasesByType(formAssigned.getMainContent()); // model.addAttribute("dbList", dbList); // 保留当前选中状态,回显到页面 model.addAttribute("formAssigned", formAssigned); return "dbAssigned"; }
2. 移除手动添加的checked属性
Thymeleaf的th:field会根据模型值自动生成checked属性,手动添加会导致绑定冲突,修改单选框代码:
<!-- 移除checked="checked" --> <input id="mainContent_rblAvailable_0" type="radio" th:field="*{mainContent}" value="1" class="ui-helper-hidden-accessible">
3. 页面加载时自动提交表单
添加JS代码,实现页面加载完成后自动提交表单,触发控制器获取单选框值:
<!-- 放在form标签结束前或页面底部 --> <script> window.addEventListener('load', function() { document.getElementById('form1').submit(); }); </script>
4. 修正多选下拉框的name属性冲突
当前多选下拉框的name="MainContent"与单选框绑定的mainContent重名,会导致参数传递混乱。修改多选框的绑定,并在模型中添加对应属性:
- 更新FormAssigned模型:
public class FormAssigned { private String mainContent; // 添加多选下拉框绑定属性 private List<String> selectedDbIds; // 原有getter/setter public String getMainContent() { return mainContent; } public void setMainContent(String mainContent) { this.mainContent = mainContent; } // 新增getter/setter public List<String> getSelectedDbIds() { return selectedDbIds; } public void setSelectedDbIds(List<String> selectedDbIds) { this.selectedDbIds = selectedDbIds; } }
- 修改多选下拉框代码:
<select id="MainContent_lbxDBList" size="23" onchange="javascript:setTimeout()" th:field="*{selectedDbIds}" style="font-size:13px;width:100%;" multiple> <!-- 用Thymeleaf循环渲染数据库选项 --> <option th:each="db : ${dbList}" th:value="${db.id}" th:title="${db.title}"></option> </select>
内容的提问来源于stack exchange,提问作者Prabhash Mishra
相关产品推荐
相关产品推荐

