I'm trying to write converter to my selectonemenu where I wan't to select object. My object ("Param") class looks like this:
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();
}
}
Bean:
@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
}
}
Converter (I know ther should be null checks and stuff):
@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());
}
}
SelectOneMenu:
<h:selectOneMenu value="#{mainBean.selectedParam}">
<f:converter converterId="paramConverter" />
<f:selectItems value="#{mainBean.params}"
var="param"
itemValue="#{param}"
itemLabel="#{param.name}"
/>
</h:selectOneMenu>
Tomcat output:
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)
I gues that getAsString method gets UnmodifiableMap object as value, but it should be Param object, am I right?
Please help me
Ps. Sorry about my english if I did some mistakes ;P
The problem is here in the var
attribute.
<f:selectItems value="#{mainBean.params}"
var="param"
itemValue="#{param}"
itemLabel="#{param.name}"
/>
The #{param}
is a reserved EL variable referring the ServletRequest#getParameterMap()
which is of type Map<String, String[]>
and indeed an unmodifiable map.
You shouldn't be using reserved EL variable names for own variables. Rename it to something else, eg _param
or so.
<f:selectItems value="#{mainBean.params}"
var="_param"
itemValue="#{_param}"
itemLabel="#{_param.name}"
/>
Your converter, albeit a bit clumsy and not entirely robust, is totally fine.
Here check that working code and try to find a mistake yourself. It will make you remember it harded:)
<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>
auctionBean (nothing special):
public Subcategory getSubCategory() {
return subCategory;
}
public void setSubCategory(Subcategory subCategory) {
this.subCategory = subCategory;
}
subcategoryConverter:
@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()));
}
}
and finally 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;
}
}
I would focus on your getAsObject method because it looks like you dont get Param object as you think you do
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.