我正在尝试做一些"自定义轻量级" JSF组件绑定。在我的bean(控制一些JSF页面)中,我声明了一个HahsMap,其中键范围超过我的h:inputText
id(出现在页面中)将这些id映射到自定义HInputText<T>
对象(T
在下面的例子中是Long)。然后我使用HInputText<T>
对象来保存相应的h: inputttext属性的子集:value
应该是类型T
, rendered
, required
等。在这个方向上,HInputText<T>
对象的字段给h:inputText
属性赋值。
我的问题是,当在h:form
中使用这样的h:inputText
时,JSF验证不会发生:我可以在h:inputText
中键入字母数字字符(应该保存一个长值),并且我的表单提交而不会显示任何错误。请注意,required
和rendered
属性被正确管理(因为required
被设置为true,当我离开h:inputText
字段为空时,我有一个错误),当我试图在使用一些h:outputText
的页面中显示h:inputText
的值时,显示字母数字字符。
是否有一些技巧可以使JSF验证工作,而不必为每个h:inputText
显式地定义自定义Validator ?
HInputText.class:
public class HInputText<T>
{
private String id;
private boolean rendered;
private boolean required;
private T value;
private Class<T> myClass;
// getters and setters for all fields
public HInputText(Class<T> myClass, String id)
{
this.myClass = myClass;
this.id = id;
this.rendered = true;
this.required = true;
}
}
管理Bean中的代码片段:
@ManagedBean(name="saisieController")
@SessionScoped
public class SaisieController
{
...
private HashMap<String,HInputText<Long>> htagLongInputTexts;
public HashMap<String, HInputText<Long>> getHtagLongInputTexts()
{
return htagLongInputTexts;
}
public void setHtagLongInputTexts(HashMap<String, HInputText<Long>> hLongInputTexts)
{
this.htagLongInputTexts = hLongInputTexts;
}
public void addHtagLongInputText(HInputText<Long> hLongInputText)
{
getHtagLongInputTexts().put(hLongInputText.getId(), hLongInputText);
}
public HInputText<Long> getHtagLongInputText(String hLongInputTextId)
{
return(getHtagLongInputTexts().get(hLongInputTextId));
}
@PostConstruct
public void init()
{
setHtagLongInputTexts(new HashMap<String, HInputText<Long>>());
addHtagLongInputText(new HInputText<Long>(Long.class, "HIT_LongTestHIT"));
}
public String doNothing()
{
return null;
}
}
最后是JSF页面的一个片段:
<h:form>
<h:inputText
id = "HIT_LongTestHIT"
value = "#{saisieController.htagLongInputTexts['HIT_LongTestHIT'].value}"
rendered = "#{saisieController.htagLongInputTexts['HIT_LongTestHIT'].rendered}"
required = "#{saisieController.htagLongInputTexts['HIT_LongTestHIT'].required}"
/>
<h:message for = "HIT_LongTestHIT" styleClass = "error-text" />
<h:commandButton value = "submit" action = "#{saisieController.doNothing()}" />
<h:outputText value = "#{saisieController.htagLongInputTexts['HIT_LongTestHIT'].value}" />
</h:form>
是否有一些技巧可以使JSF验证工作而不必显式地为每个h:inputText定义自定义Validator ?
不,那不可能。由于类型擦除,泛型类型信息在运行时不可用。JSF/EL不知道T
实际上是一个Long
,更不用说实际上存在一些 T
。您确实需要显式地指定一个转换器,在这个特定的示例中是LongConverter
,转换器ID为javax.faces.Long
。
<h:inputText ... converter="javax.faces.Long">
或者动态的
<h:inputText ...>
<f:converter converterId="#{saisieController.htagLongInputTexts['HIT_LongTestHIT'].converterId}" />
</h:inputText>
您可以在javax.faces.convert
包摘要中找到所有可用的标准JSF转换器的概述。您可以通过导航到公共常量CONVERTER_ID
上的Constant字段值链接来查找它们的转换器id。