我有一个ccomposite功能,它包含SelectOneMenu Control和它的Backing Bean来加载SelectOneMenu Control的数据。并且还有一个用于SelectOneMEnu控件的自定义转换器。现在我想从FacesConverter的'getAsObject'方法获取BackingBean。所以当我发布页面组件时,不会将值绑定到CDI beans字段。我的转换器和其他代码如下。
这是转换器类。
@FacesConverter(value = "AccountConverter", forClass=Account.class)
public class AccountConverter implements Converter
{
private static final long serialVersionUID = 1L;
@Override
public Object getAsObject(FacesContext ctx, UIComponent uiComponent, String arg2)
{
ValueExpression vex = ctx.getApplication().getExpressionFactory().createValueExpression(ctx.getELContext(),"#{AccountComponent}", AccountComponent.class);
AccountComponent accComponent = (AccountComponent)vex.getValue(ctx.getELContext());
Account racc=accComponent.GetAccount(Integer.valueOf(arg2)); // This methos returns Null
return racc;
}
@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object account) {
Account accctemp=((Account)account);
Integer accid=accctemp.getAccountId();
return accid.toString();
}
}
问题是;我无法获得复合控件的BackingBean(AccountComponent)。 我的意思是'vex.getValue'方法返回NUll。由于这个原因我无法访问SelectOneMenu控件的选定对象。我的所有其他代码如下。
他是复合控制。
<ui:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite">
<cc:interface componentType="AccountComponent">
<cc:attribute name="value" type="com.abank.pojo.Account" shortDescription="Account Class" />
<cc:attribute name="CurrencyCode" />
<cc:attribute name="CurrencyCode" />
<cc:attribute name="ajaxEventListener" method-signature="void f1(javax.faces.event.AjaxBehaviorEvent)" />
</cc:interface>
<cc:implementation>
<f:event type="postAddToView" listener="#{cc.init}" />
<h:outputStylesheet library="css" name="selec2.css" target="head" />
<h:outputScript library="js" name="select2.full.js" target="head" />
<h:outputScript library="js" name="AccountComponent.js" target="head" />
<div class="form-group">
<h:outputLabel value="Hesap" />
<div></div>
<h:selectOneMenu id="drpAccount" width="75%"
value="#{cc.attrs.value}"
converter="AccountConverter"
styleClass="form-control">
<f:selectItems var="myaccount" value="#{cc.accounts}"
itemLabel="#{myaccount.ibanNumber}" itemValue="#{myaccount}" />
</h:selectOneMenu>
</div>
</cc:implementation>
</ui:component>
复合控制的BackingBean。
@FacesComponent("AccountComponent")
public class AccountComponent extends UIInput implements NamingContainer {
private List<Account> accounts;
public void init() {
String attr = this.getAttributeValue("CurrencyCode", "ALL");
accounts=AccountRepo.AccountComponentLoadDataFromService(attr);
}
public Account GetAccount(Integer id) {
if (id == null) {
throw new IllegalArgumentException("no id provided");
}
if (accounts == null)
return null;
for (Account acc : accounts) {
if (id.equals(acc.getAccountId())) {
return acc;
}
}
return null;
}
@Override
public String getFamily() {
return("javax.faces.NamingContainer");
}
// Helpers
// ------------------------------------------------------------------------------------
@SuppressWarnings({ "unchecked", "unused" })
private <T> T getAttributeValue(String key, T defaultValue) {
T value = (T) getAttributes().get(key);
return (value != null) ? value : defaultValue;
}
public String GetJsonFromObject() {
return this.toString();
}
// Getters/setters
// ----------------------------------------------------------------------------
@Override
public String toString() {
ObjectMapper mapper = new ObjectMapper();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
mapper.setDateFormat(df);
String jsonInString = "";
try {
jsonInString = mapper.writeValueAsString(this.accounts);
} catch (Exception e) {
}
return jsonInString;
}
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
}
最后一个是我使用该组件的JSf页面。
<my:AccountComponent id="drpSourceAccount"
CurrencyCode="YTL"
value="#{moneyOrderBean.sourceAccount}" >
</my:AccountComponent>