h:selectManyListbox を h:messages に関連付けてレンダリングする必要がある単純な複合コンポーネントがあります。問題は、faces コンバーター クラスの使用にあります。それは動作していないようです (コンポーネント コードで使用されている場合のみ)。
複合コンポーネント コード:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:composite="http://java.sun.com/jsf/composite">
<!-- INTERFACE -->
<composite:interface>
<composite:attribute name="description" required="true" />
<composite:attribute name="fieldValue" required="true" />
<composite:attribute name="idc" required="true" />
<composite:attribute name="size" required="true" />
</composite:interface>
<!-- IMPLEMENTATION -->
<composite:implementation>
<tr>
<td nowrap="nowrap">
<h:outputText value="#{cc.attrs.description}" />
</td>
<td>
<h:selectManyListbox
id="#{cc.attrs.idc}"
size="#{cc.attrs.size}"
value="#{cc.attrs.fieldValue}">
<composite:insertChildren />
</h:selectManyListbox>
</td>
<td>
<h:message for="#{cc.attrs.idc}" />
</td>
</tr>
</composite:implementation>
</html>
sample.xhtml ページで使用すると (以下に示すように)、「検証エラー: 値が無効です」というメッセージが表示されます。.....
しかし、同じページに次のようなコードを入れたとき:
<tr>
<td><h:outputText value="Plugins" /></td>
<td>
<h:selectManyListbox
id="plugins"
value="#{bean.currentPlugins}"
size="6">
<f:selectItems value="#{bean.availablePlugins}" />
</h:selectManyListbox>
</td>
<td><h:message for="plugins" /></td>
</tr>
すべてうまくいく。
マネージド Bean の「bean」クラスは
@ManagedBean
@SessionScoped
public class Bean extends GenericManagedBean
implements Serializable {
ElementClass[] currentPlugins;
// getter & setter for currentPlugins
// ...
public List<ElementClass> getAvailablePlugins() {
// .. some code
return list;
}
}
ElementClassは
public class ElementClass extends GenericEntity implements Serializable {
private static final long serialVersionUID = 9159873495276902436L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "ID")
private Integer id;
// other fields
// ...
// getters & setters
// ...
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof ElementClass)) {
return false;
}
ElementClass other = (ElementClass) object;
if ((this.id == null && other.id != null)
|| (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
}
ElementClass の場合、コンバーター クラスがあります
@FacesConverter(forClass = ElementClass.class)
public class ElementClassConverter implements Converter {
@Override
public Object getAsObject(FacesContext fc, UIComponent uiComponent,
String elemId) {
if (!StringUtils.isEmpty(elemId)) {
// this code gets ElementClass object entity from database
ApplicationBean applicationBean = JSFHelper
.findBean("applicationBean");
return applicationBean.getService()
.findElementClassById(
Integer.parseInt(elemId));
} else {
return null;
}
}
@Override
public String getAsString(FacesContext fc, UIComponent uiComponent,
Object elem) {
return elem != null ? ((ElementClass ) elem).getId()
.toString() : "";
}
}
そして、標準的な質問: 私は何を間違っていますか? これはjsf実装のバグではなく、私の知識不足だと思います。私は JBoss 7.1.1 AS とそれにバンドルされているものすべて + RichFaces 4 を使用しています。