我们有一个带有<rich:tab>
的JSF应用程序,它根据存储在数据库中的某些配置显示字段,因此组件未在.xhtml页面中定义,但必须以编程方式生成,如下例所示:
组件在面板中生成:
<rich:tab id="someTab" header="#{msg['someHeader']}" immediate="true">
<rich:messages/>
<h:panelGrid id="generatedComponentsContainer"/>
</rich:tab>
组件生成示例(为简单起见而简化):
FacesContext ctx = FacesContext.getCurrentInstance();
UIPanel panel = (UIPanel) ctx.getViewRoot().findComponent("someForm:generatedComponentsContainer");
text = (UIInput) ctx.getApplication().createComponent(ctx, "javax.faces.Input", "javax.faces.component.UIInput");
text.getAttributes().put("label", someLabel);
panel.getChildren().add(text);
这些组件必须根据某些条件显示为禁用,因此我使用以下代码在需要时禁用它们:
if (!showEnabled) { text.getAttributes().put("disabled", "true"); }
此方法适用于UIInput
和HtmlInputTextarea
,但它不适用于UICalendar
,只会投放IllegalArgumentException (argument type mismatch)
。
如何禁用日历?
我一直想知道这段代码是否只是禁用客户端的组件,而是在服务器上启用它。这可能是一个安全威胁,因为有人可以通过Javascript启用组件并将表单提交给服务器。我不确定这是否可能,请告知我是否错了。
答案 0 :(得分:0)
经过进一步研究后,我注意到有一些类扩展了我们在项目中使用的类。这些类具有禁用属性的getter / setter,它还会禁用服务器端的组件。我测试了这个以编程方式禁用组件并在浏览页面时删除了disabled属性以允许编辑和提交。提交表单时,值在请求中设置,但在服务器端被忽略。 Bean值保持不变。
我们使用的课程:
HtmlInputTextarea
代替UIInput
HtmlInputText
代替UIInput
我们已经在使用符合目的的UICalendar
代码示例:
HtmlInputText text = (HtmlInputText) ctx.getApplication().createComponent(
ctx, HtmlInputText.COMPONENT_TYPE, "javax.faces.component.html.HtmlInputText");
if (!showEnabled) { text.setDisabled(true); }
调试HtmlInputText
的内容时,您可以看到一个ComponentStateHelper
对象(名为stateHelper
),它存储组件的禁用状态(以及其他数据)。它的超接口是StateHolder
:
public interface StateHolder
此接口由需要保存其状态的类实现 请求之间。
我知道组件的服务器端状态存储在此对象中,但我不确定它是仅存储在此处还是存储在更多点中,或者即使我对其目的的解释是正确的。专家的反馈非常有用。