我正在尝试将list of objects
映射到<p:selectOneMenu
(如下所示的代码):
Attribute.java
public class Attribute implements Serializable {
private String name;
private String type;
private String value; //getters setters constructors ommitted
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Attribute attribute = (Attribute) o;
return Objects.equals(name, attribute.name) &&
Objects.equals(type, attribute.type);
}
@Override
public int hashCode() {
return Objects.hash(name, type, value);
}
p:selectOneMenu代码
<p:selectOneMenu label="Existing Attributes" value="#{cellBean.selectedAttributeFromExistings}"
converter="attrConverter">
<f:selectItem itemLabel="Existing attribute" itemValue="#{null}" itemDisabled="true"/>
<f:selectItems value="#{cellBean.allAttributes}" var="attr" itemLabel="#{attr.name}" itemValue="#{attr}"/>
<p:ajax event="change" update="@form" process="@form"/>
</p:selectOneMenu>
属性转换器(attrConverter)代码
@FacesConverter(forClass=Attribute.class, value = "attrConverter")
public class AttributeConverter implements Converter {
@Override
public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String s) {
String type = s.substring(s.indexOf(":") + 2, s.indexOf(","));
String name = s.substring(s.indexOf("name: ") + 6 , s.length());
Attribute attribute = new Attribute(type, name);
return attribute;
}
@Override
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object attr) {
if(attr == null) {
return null;
}
else{
Attribute attribute = new Attribute();
String s = "";
Iterator iterator = ((LinkedTreeMap)attr).keySet().iterator();
while(iterator.hasNext()){
String key = (String) iterator.next();
String value = (String) ((LinkedTreeMap)attr).get(key);
if(key.equals("name")){
attribute.setName(value);
}
else if(key.equals("type")){
attribute.setType(value);
}
}
return attribute.toString();
}
}
但是,当我从下拉菜单中选择一个值时,出现以下异常
验证错误:值无效:验证错误:值无效
紧随其后的是错误消息/在屏幕右上角弹出,您知道我在做什么错吗?
PS:我已经看到许多示例,它们使用unique id
来通过getAsObject
方法中的DTO检索对象,在我的示例中,{ uniqueness
对象的{1}}是Attribute
个成员变量的组合。
在此先感谢您的帮助:)
答案 0 :(得分:2)
我不知道为什么将attr强制转换为LinkedTreeMap
类,您需要将其强制转换为Attribute
类。所以您的转换器类应该是:
@FacesConverter(forClass=Attribute.class, value = "attrConverter")
public class AttributeConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value != null && value.trim().length() > 0 && !value.isEmpty()) {
/*I take your bean as ViewScoped */
CellBean cellBean = (CellBean) context.getViewRoot().getViewMap().get("cellBean");
for(Attribute a : cellBean.getAllAttributes()){
String combined = a.getType()+a.getValue();
if(combined.equals(value)){
return a;
}
}
}
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value != null) {
Attribute a = (Attribute) value;
return a.getType()+a.getValue();
}
return null;
}
}
更新
面向问询者:
@Override
public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String s) {
String[] typeAndName = s.split("#");
return new Attribute(typeAndName[0], typeAndName[1]);
}
@Override
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object attr) {
if(attr == null) {
return null;
}
else{
/* I assume your type and name don't contain '#' charachter */
return ((Attribute)attr).getType()+"#"+((Attribute)attr).getName();
}
}
答案 1 :(得分:0)
问题的根源是我使用gson
进行了错误的序列化,我将Attribute
对象转换为LinkedTreeMap
,这也是注释部分中提到的缺点。当我正确进行序列化时,getAsObject
和getAsString
函数具有以下形式:
@Override
public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String s) {
String type = s.substring(s.indexOf("type=") + 5, s.indexOf(" "));
String name = s.substring(s.indexOf("name=") + 5 , s.length());
Attribute attribute = new Attribute(type, name);
return attribute;
}
@Override
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object attr) {
if(attr == null) {
return null;
}
else{
return "type="+((Attribute)attr).getType()+" name="+((Attribute)attr).getName();
}
}