Struts2升级至6.3.0.2后单选按钮选中状态前端不回显
系统从Struts2升级至Struts 6.3.0.2后,出现如下异常:
- 单选按钮可正常选择,数据能成功保存至数据库
- 控制台可查到数据库返回的选中值,但前端页面无法回显选中状态
- 控制台及Edge开发者工具均无报错信息
相关代码
Java Action代码
public class getDotsCarRentalAction extends GenericMappingDispatchAction{ public String saveCr(){ HttpSession session = request.getSession(); String result = null; DotsCarRentalForm frm = null; DotsCarRental dotsCarRental = new DotsCarRental(); dotsCarRental = (DotsCarRental) session.getAttribute(DBConstants.sessionCarId); frm = (DotsCarRentalForm) form; dotsCarRental = frm.getFormData(dotsCarRental); result = frm.getFctSelected().trim(); if(result == null || result.length() < 1) result = "CARRENTAL"; ActionErrors errors = frm.validate(getTextProvider(),request); if(errors != null){ saveErrors(errors); return "CARRENTAL"; } session.setAttribute(DBConstants.sessionCarId,dotsCarRental); return result; } public String getCr(){ HttpSession session = request.getSession(); DotsCarRental dotsCarRental = new DotsCarRental(); dotsCarRental = (DotsCarRental) session.getAttribute(DBConstants.sessionCarId); DotsCarRentalForm frm = new DotsCarRentalForm(); if(dotsCarRental !=null){ frm.setFormData(dotsCarRental); } frm.setFctSelected(null); frm.setValSelected(null); request.setAttribute("dotsCarRentalForm",frm); return "success"; } }
前端JSP及配置代码
<div class="form-group" style="width:100%; clear: both;"> <div>Staff</div><br /> <s:iterator var="srr" value="#rr"> <span> <s:radio name="rentalReason" style="font-weight: normal; padding: 2px; word-wrap: break-word;" value="#frm.rentalReason" list="#srr" listKey="lookupTitle" listValue="lookupTitle" /><br/> </span> </s:iterator> </div> <div> <a class="btn btn-outline-primary" href="javascript:document.forms[0].fctSelected.value='SAVEEOTAF';document.forms[0].submit();">SAVE AS DRAFT</a> </div> <!--struts-dots.xml--> <action name="SaveDotsCarRental" class="com.dots.action.getDotsCarRentalAction" method="saveCr"> <!--struts-generated.xml--> <action name="SaveDotsCarRental" class="com.dots.action.getDotsCarRentalAction" method="saveCr"> <!--viewDotsCarRental.jsp--> <form name="form" method="post" action="SaveDotsCarRental.do" onsubmit="return false">
排查方向及解决建议
修正OGNL表达式的上下文引用
在getCr方法中,表单对象被设置为request.setAttribute("dotsCarRentalForm",frm);,但页面中<s:radio>的value属性使用了#frm.rentalReason,OGNL无法识别未正确命名的上下文变量。需将value属性改为#dotsCarRentalForm.rentalReason,或者在Action中添加DotsCarRentalForm类型的成员变量并提供getter方法,让Struts自动绑定上下文。校验值与listKey的类型一致性
Struts 6.x对类型匹配的校验比Struts2更严格,确认#dotsCarRentalForm.rentalReason的类型和listKey="lookupTitle"的类型完全一致(包括字符串大小写、数据类型),类型不匹配会导致选中状态无法正确匹配。调整表单数据传递方式
放弃手动设置request属性的方式,在Action中添加private DotsCarRentalForm dotsCarRentalForm;及对应的getter/setter方法,在getCr方法中直接给该成员变量赋值。此时<s:radio>标签可省略value属性,Struts会自动匹配与name属性对应的Action字段值。检查OGNL配置兼容性
查看struts.xml中的OGNL相关配置,确保与Struts2时期一致,例如:<constant name="struts.ognl.allowStaticMethodAccess" value="true"/> <constant name="struts.ognl.enableExpressionCache" value="true"/>配置缺失或变更可能导致OGNL表达式解析失败,进而影响回显逻辑。
查看页面渲染源码
右键查看页面HTML源码,检查生成的单选按钮input标签是否带有checked属性:- 若没有,说明Struts标签未正确计算选中状态,需重新校验表达式和数据绑定;
- 若有但页面未显示,可能是CSS样式覆盖了默认选中样式,检查相关样式规则。
内容的提问来源于stack exchange,提问作者Mahabir Gupta

