Java jsf转换器:如何找出实际传递的值字符串的类类型?
我试图将自定义类对象与MyFacesUI组件(如复选框/组合框等)绑定在一起,但没有通过在支持bean中创建getter/setter来提供int/float/boolean/String/List等显式类型 所以在我的例子中,它通常是这样的:Java jsf转换器:如何找出实际传递的值字符串的类类型?,java,jsf,generics,Java,Jsf,Generics,我试图将自定义类对象与MyFacesUI组件(如复选框/组合框等)绑定在一起,但没有通过在支持bean中创建getter/setter来提供int/float/boolean/String/List等显式类型 所以在我的例子中,它通常是这样的: <h:selectOneListbox id="mylist" value="#{bean.myListValueHolder.data}" converter="myValueConverter"> ... </h:s
<h:selectOneListbox id="mylist" value="#{bean.myListValueHolder.data}"
converter="myValueConverter">
...
</h:selectOneListbox>
我的转换器:
public Object getAsObject(FacesContext fc, UIComponent c, String value) {
...
问题:如何查找在运行时作为值传递的类型?在我的例子中,它可以是布尔、int、float、double、String或List
但我有点不喜欢写作
键
,值
对。My UI元素还有一个特定的状态
(EnumSet from a状态
-Enum{隐藏、可见、禁用、启用、悬停、聚焦、活动等),它依赖于存储在值持有者
中的特定值。所需状态的依赖关系在规则
类中描述,该类具有状态
的枚举集
和匹配
方法,如果由于规则
匹配而应应用定义的状态
,则返回真
。然后我有一个值更改侦听器
,它将应用新的状态
如果值
已更改,且与该值
关联的规则
匹配,则返回UI组件
至少我是这样想的,我可以这样做。所以我可以从我的视图中查询值和ui状态,如果一些具体的值发生了变化,这反过来可能会改变UIComponent
的状态,我可以调用回调,并根据新的状态
通过JQ向该特定组件添加/删除一个新的css类乌利
嗯,听起来有点复杂或有些过火,但我想用Java定义我的UI组件状态
,这样我也可以从Java更改状态
,而不必在视图中定义状态规则。您可以将转换器的实例添加到bean中,并将其绑定到输入元素,然后您就知道类型了您还可以通过构造函数将要转换的对象传递给转换器,并执行简单的查找。虽然不是很漂亮,但它可以工作。您可以将转换器的实例添加到bean中,并将其绑定到输入元素,然后您就知道了类型。这样,您还可以通过构造函数将要转换的对象传递给转换器或者,执行简单的查找。虽然不是很漂亮,但它会工作。JSF转换器不适合这种情况。您需要对此进行自定义。扩展和重写getType()
,getValue()
和setValue()
在这里,您可以获取具体的值持有者
实现。通过这种方式,您最终可以得到像value=“#{bean.myStringValueHolder}”
这样的表达式,而不需要.data
。这样,数据强制/转换将由JSF/EL自动完成
您可以通过应用程序#addELResolver()
在应用程序启动时注册自定义EL解析器:
至于泛型类型的计算,假设ValueHolder
是一个抽象类
,并且您有具体的实现,比如StringValueHolder扩展了ValueHolder
等等,那么您将能够在ValueHolder
的构造函数中提取泛型类型
public abstract class ValueHolder<T extends Comparable<T>> extends Node<T> {
private Class<T> type;
private T data;
@SuppressWarnings("unchecked")
public ValueHolder() {
this.type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public Class<T> getType() {
return type;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public void setData(Object data) {
this.data = type.cast(data);
}
}
公共抽象类ValueHolder扩展节点{
私人阶级类型;
私有T数据;
@抑制警告(“未选中”)
公共估价师(){
this.type=(Class)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
公共类getType(){
返回类型;
}
公共T getData(){
返回数据;
}
公共无效设置数据(T数据){
这个数据=数据;
}
公共void setData(对象数据){
this.data=type.cast(数据);
}
}
我只想知道整个方法是如何有用的。有一些看似不必要的开销。功能需求到底是什么?它只是消除了getter/setter样板文件?为什么不只是使用模型对象(javabeans/entities/etc)因此,您最终在支持bean中只有一个模型属性?它是否厌倦了每次键入它们?一个体面的IDE可以自动生成它们。更重要的是,完整的javabean类可以根据属性名称列表和几次单击自动生成。JSF转换器不适用于此。您需要为扩展和重写getType()
,getValue()
和setValue()
在其中获取具体的ValueHolder
实现就应该做到这一点。这样,最终可以得到value=“#{bean.myStringValueHolder}”这样的表达式
不使用.data
。这样,数据强制/转换将由J自动完成
public Object getAsObject(FacesContext fc, UIComponent c, String value) {
...
FacesContext.getCurrentInstance().getApplication().addELResolver(new ValueHolderELResolver());
public abstract class ValueHolder<T extends Comparable<T>> extends Node<T> {
private Class<T> type;
private T data;
@SuppressWarnings("unchecked")
public ValueHolder() {
this.type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public Class<T> getType() {
return type;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public void setData(Object data) {
this.data = type.cast(data);
}
}