JSF场景下<ui:include>未触发Setter,无法设置值求助
嘿,我来帮你搞定这个Setter不触发的麻烦!结合你给出的代码片段,咱们一步步拆解可能的原因:
先确认
<ui:param>传递的对象是否具备可修改条件
你通过<ui:param name="element" value="${entry}"/>把entry传给了包含页面,首先要检查:entry是不是一个标准的可变JavaBean实例——属性不能是final修饰的,必须有符合规范的Setter方法(比如setContent(String content)这种签名,大小写要严格对应Getter)。manager.page.content这个ArrayList里的对象,是不是在请求过程中保持了实例的一致性,没有被重新创建或者替换。
检查包含页面(Question.xhtml)的输入组件绑定是否正确
比如在Question.xhtml里的输入组件,必须是像<h:inputText value="#{element.yourProperty}"/>这样的绑定:- 属性名要和JavaBean的Getter/Setter完全匹配(JSF对大小写极其敏感,
getUserName()对应#{element.userName},不能写成username)。 - 所有输入组件必须包裹在
<h:form>标签内!没有表单的话,JSF根本不会处理提交的值,Setter自然不会被调用。
- 属性名要和JavaBean的Getter/Setter完全匹配(JSF对大小写极其敏感,
<ui:repeat>的数据源要稳定可追踪
JSF在处理<ui:repeat>的表单提交时,需要manager.page.content这个ArrayList能稳定提供相同顺序的实例,且每个entry最好重写了equals()和hashCode()方法。如果Bean是@RequestScoped作用域,每次请求都会重建Bean,之前的page.content会丢失,也会导致Setter失效——建议用@ViewScoped来保持视图状态的连续性。注意
<h:panelGroup>的rendered属性一致性
你用了<h:panelGroup rendered="${entry.type eq 1}">,这个属性在表单渲染时和提交时的计算结果必须完全一致!如果提交时entry.type的值变了,或者因为Bean作用域问题导致entry实例更换,JSF会认为这个组件不存在,里面的输入值就不会被处理,Setter也就不会触发。可以把entry.type的判断依据存在稳定的地方(比如视图参数),确保提交时条件和渲染时一致。排查是否有Validation(验证)错误
如果输入组件的验证失败,JSF会直接跳过Setter调用。你可以在页面上添加<h:messages globalOnly="true"/>,或者给每个输入组件加<h:message for="组件ID"/>,看看有没有隐藏的验证错误(比如格式不符合要求、必填项未填写等)。
小测试技巧
你可以先简化代码:去掉<ui:include>和rendered属性,直接在<ui:repeat>里放一个简单的<h:inputText value="#{entry.someProperty}"/>,测试Setter能不能触发。如果可以,再逐步加回原来的代码,就能定位到具体是哪个环节出了问题。
内容的提问来源于stack exchange,提问作者Torain

