2

我正在尝试将转换器写入我不想选择对象的 selectonemenu。我的对象(“参数”)类如下所示:

public class Param {
private Integer id;
private String name;

public Param(Integer id, String name){
    this.id = id;
    this.name = name;
}

public Integer getId(){
    return this.id;
}
public String getName(){
    return this.name;
}

@Override
public boolean equals(Object object) {
    return (object instanceof Param) && (id != null) 
         ? id.equals(((Param) object).getId()) 
         : (object == this);
}

@Override
public int hashCode() {
    return (id != null)
        ? (this.getClass().hashCode() + id.hashCode())
        : super.hashCode();
}

}

豆:

@ManagedBean
@SessionScoped
public class MainBean {
private List<Param> params;
private Param selectedParam;


public List<Param> getParams(){
    return this.params;
}
public Param getSelectedParam(){
    return this.selectedParam;
}
public void setSelectedParam(Param param){
    this.selectedParam = param;
}


public MainBean(){
    //filling params - works good
}

}

转换器(我知道应该是空检查和东西):

@FacesConverter(value = "paramConverter", forClass = Param.class)
public class ParamConverter implements Converter {
private List<Param> getParams(){
    ExternalContext tmpEC;
    Map sMap;
    tmpEC = FacesContext.getCurrentInstance().getExternalContext();
    sMap = tmpEC.getSessionMap();
    MainBean mainBean = (MainBean) sMap.get("mainBean");
    return mainBean.getParams();
}

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
    Integer id = Integer.valueOf(value);
    List<Param> params = this.getParams();
    Param param = null;
    for(int i=0; i < params.size(); i++){
        if(id == params.get(i).getId()){
            param = params.get(i);
            break;
        }
    }
    return param;
}

@Override
public String getAsString(FacesContext context, UIComponent component, Object value)
{
    Param param = (Param)value;
    return String.valueOf(param.getId());
}

}

选择一个菜单:

<h:selectOneMenu value="#{mainBean.selectedParam}">
<f:converter converterId="paramConverter" />
<f:selectItems value="#{mainBean.params}"
var="param" 
itemValue="#{param}" 
itemLabel="#{param.name}" 
/>
</h:selectOneMenu>

雄猫输出:

HTTP Status 500 - java.util.Collections$UnmodifiableMap cannot be cast to Param

--------------------------------------------------------------------------------

type Exception report

message java.util.Collections$UnmodifiableMap cannot be cast to Param

description The server encountered an internal error that prevented it from fulfilling this request.

exception 

javax.servlet.ServletException: java.util.Collections$UnmodifiableMap cannot be cast to Param
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)


root cause 

java.lang.ClassCastException: java.util.Collections$UnmodifiableMap cannot be cast to Param
    ParamConverter.getAsString(ParamConverter.java:40)
    com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getFormattedValue(HtmlBasicRenderer.java:521)
    com.sun.faces.renderkit.html_basic.MenuRenderer.renderOption(MenuRenderer.java:534)
    com.sun.faces.renderkit.html_basic.MenuRenderer.renderOptions(MenuRenderer.java:794)
    com.sun.faces.renderkit.html_basic.MenuRenderer.renderSelect(MenuRenderer.java:847)
    com.sun.faces.renderkit.html_basic.MenuRenderer.encodeEnd(MenuRenderer.java:297)
    javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:919)
    javax.faces.component.UIComponent.encodeAll(UIComponent.java:1903)
    javax.faces.render.Renderer.encodeChildren(Renderer.java:176)
    javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:889)
    com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:304)
    com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:115)
    javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:889)
    javax.faces.component.UIComponent.encodeAll(UIComponent.java:1896)
    javax.faces.render.Renderer.encodeChildren(Renderer.java:176)
    javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:889)
    javax.faces.component.UIComponent.encodeAll(UIComponent.java:1896)
    javax.faces.component.UIComponent.encodeAll(UIComponent.java:1899)
    javax.faces.component.UIComponent.encodeAll(UIComponent.java:1899)
    com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:451)
    com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
    com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
    com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)

我猜 getAsString 方法将 UnmodifiableMap 对象作为值,但它应该是 Param 对象,对吗?

请帮我

附言。如果我犯了一些错误,对不起我的英语;P

4

2 回答 2

2

问题出在var属性中。

<f:selectItems value="#{mainBean.params}"
    var="param" 
    itemValue="#{param}" 
    itemLabel="#{param.name}" 
/>

The#{param}是一个保留的 EL 变量,它指的ServletRequest#getParameterMap()是它的类型Map<String, String[]>,实际上是一个不可修改的映射。

您不应该为自己的变量使用保留的 EL 变量名。将其重命名为其他名称,例如_param左右。

<f:selectItems value="#{mainBean.params}"
    var="_param" 
    itemValue="#{_param}" 
    itemLabel="#{_param.name}" 
/>

您的转换器虽然有点笨拙且不完全稳健,但完全没问题。

于 2013-11-12T11:22:15.780 回答
-2

在这里检查该工作代码并尝试自己找出错误。它会让你很难记住它:)

                                <h:selectOneMenu rendered="#{categoryConverterBean.rendered}" class="subcategory" id="subcategory" converter="#{subcategoryConverterBean}" value="#{auctionBean.subCategory}">  

                                    <f:selectItems 
                                        value="#{categoryListBean.subcategory}" 
                                        var="subcategory"
                                        itemLabel="#{subcategory.subName}" 
                                        itemValue="#{subcategory}" 
                                        />
                                </h:selectOneMenu>

拍卖豆(没什么特别的):

public Subcategory getSubCategory() {
    return subCategory;
}

public void setSubCategory(Subcategory subCategory) {
    this.subCategory = subCategory;
}

子类别转换器:

@ManagedBean(name = "subcategoryConverterBean") 
@FacesConverter(value = "subcategoryConverter")
public class SubcategoryConverter implements Converter {

    @PersistenceContext()
    private transient EntityManager em;

    @Override
    public Object getAsObject(FacesContext arg0, UIComponent arg1, String value) {
        // TODO Auto-generated method stub
            System.out.println("wybrales: " + value);
        Query query = em.createQuery("SELECT c FROM Subcategory c WHERE c.subId=?1");
        query.setParameter("1", Integer.parseInt(value));

        return query.getSingleResult();
    }

    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object value) {
        // TODO Auto-generated method stub
        return ((String) String.valueOf(((Subcategory) value).getSubId()));
    }

}

最后是 categoryListBean:

@ManagedBean
public class CategoryListBean {

    private List<CategoryBean> category;
    private List<SubcategoryBean> subcategory;

    @EJB
    CategoryEAO service;

    public List<CategoryBean> getCategory() {
        category = service.getCategories();
        return category;
    }

    public void setCategory(List<CategoryBean> category) {
        this.category = category;
    }

    public List<SubcategoryBean> getSubcategory() {
        subcategory = service.getSubcategories();
        return subcategory;
    }

    public void setSubcategory(List<SubcategoryBean> subcategory) {
        this.subcategory = subcategory;
    }
}

我会专注于您的 getAsObject 方法,因为看起来您没有像您认为的那样获得 Param 对象

于 2013-11-11T22:57:59.700 回答