我成功实现了一个bean使用的h:selectOneMenu
转换器,但是我想从另一个bean使用相同的转换器,而不是另一次创建相同的转换器。
目前我有:
变流器
@FacesConverter(value = "csiConverter")
public class CsiConverter implements Converter {
@Override
public Object getAsObject(FacesContext ctx, UIComponent uiComponent, String dcId) {
ValueExpression vex =
ctx.getApplication().getExpressionFactory()
.createValueExpression(ctx.getELContext(),
"#{cfgbean}", CfgDbBean.class);
...
}
@Override
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object o) {
return ((Csi) o).getCsi();
}
和xhtml
<div class="form-group">
<label>CSI</label>
<h:selectOneMenu id="csi" styleClass="form-control" value="#{cfgbean.csi}" converter="csiConverter">
<f:selectItems var="csival" itemLabel="#{csival.csi} - #{csival.name}" itemValue="${csival}" value="#{cfgbean.csilist}" />
</h:selectOneMenu>
</div>
这一切都很好。现在我想在不同的xhtml中创建相同的selectOneMenu
,联系不同的bean以达到相同的目的,以显示相同的内容。
问题是Converter类内部是有线bean引用和bean类。(createValueExpression(ctx.getELContext(), "#{cfgbean}", CfgDbBean.class);
)
怎么可以避免索引并为所有豆类提供通用的csiConverter
?
谢谢
我有一个转换器,其中getAsObject
方法可选地使用属性来传递bean名称。如果未设置该属性,则使用组件的value属性来检测值绑定到的对象的类型:
ValueExpression valueExpression = uiComponent.getValueExpression("value");
Class<?> type = valueExpression.getType(ctx.getELContext());
从类型I可以确定bean名称。这也可能是您的选择。
就我而言:
String beanName = type.getSimpleName() + "Bean";
beanName = beanName.substring(0, 1).toLowerCase() +
beanName.substring(1);
如果在不同的bean上使用相同的类型,则应该能够从以下位置获取bean名称:
valueExpression.getExpressionString()
它返回用于创建表达式的原始字符串,未经修改。在你的情况下:
#{cfgbean.csi}
只需从该字符串中删除.csi
部分即可获得该bean。如果你的bean扩展了一个抽象bean /实现了一个像CsiHolder
这样的接口(或者你给它的任何名字),你可以得到像这样的bean:
ctx.getApplication().evaluateExpressionGet(ctx, "#{cfgbean}", CsiHolder.class)
这是在Jasper的帮助下完成的部分。
ValueExpression valueExpression = uiComponent.getValueExpression("value");
String beanName = valueExpression.getExpressionString();
//#{formbean.data}
if(beanName.contains("#{")){
String[] output = beanName.split("\\{");
if(output.length!=2){
throw new IllegalArgumentException(beanName + " - invalid format!");
}else{
if(output[1].contains(".")){
String[] bean = output[1].split("\\.");
beanName = bean[0];
}else{
throw new IllegalArgumentException(output[1] + " - invalid format!");
}
}
}else{
throw new IllegalArgumentException(beanName + " - invalid format!");
}
Object p = ctx.getApplication().evaluateExpressionGet(ctx, "#{"+beanName+"}", Object.class);
if(p instanceof FormBean){
FormBean p2 = (FormBean) p;
return p2.getName(dcId);
}
...
...
...
它工作正常,我解决了这个问题。