I currently have a JSF application that uses two listboxes. The first, say ListBox1, contains a list of manufacturers; each option comes from the database (via a method getManufacturers in a class called QueryUtil), is populated dynamically, and its value is an integer ID. This part works so far.
My goal is to populate a second listbox, say ListBox2, with a list of products sold by the manufacturer. This list of products will come from the database as well (products are linked to a manufacturer via a foreign key relationship, via a method getProducts in my QueryUtil class). How do I go about doing this? Please bear in mind that I've been working with JSF for under 24 hours; I'm willing to accept the fact that I'm missing something very rudimentary.
Again, I've been able to populate the list of manufacturers just fine; unfortunately, adding the Products component gives me java.lang.IllegalArgumentException: argument type mismatch
faces-config.xml
<managed-bean>
<managed-bean-name>ProductsBean</managed-bean-name>
<managed-bean-class>com.nieltown.ProductsBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>manufacturers</property-name>
<property-class>java.util.ArrayList</property-class>
<value>#{manufacturers}</value>
</managed-property>
<managed-property>
<property-name>selectedManufacturer</property-name>
<property-class>java.lang.Integer</property-name>
<value>#{selectedManufacturer}</value>
</managed-property>
<managed-property>
<property-name>products</property-name>
<property-class>java.util.ArrayList</property-class>
<value>#{products}</value>
</managed-property>
<managed-property>
<property-name>selectedProduct</property-name>
<property-class>java.lang.Integer</property-name>
<value>#{selectedProducts}</value>
<managed-property>
</managed-bean>
com.nieltown.ProductsBean
public class ProductsBean {
private List<SelectItem> manufacturers;
private List<SelectItem> products;
private Integer selectedManufacturer;
private Integer selectedProduct;
public ProductsBean() {}
public Integer getSelectedManufacturer(){
return selectedManufacturer;
}
public void setSelectedManufacturer(Integer m){
selectedManufacturer = m;
}
public Integer getSelectedProduct(){
return selectedProduct;
}
public void setSelectedProduct(Integer p){
selectedProduct = p;
}
public List<SelectItem> getManufacturers(){
if(manufacturers == null){
SelectItem option;
plans = new ArrayList<SelectItem>();
QueryUtil qu = new QueryUtil();
Map<Integer, String> manufacturersMap = qu.getManufacturers();
for(Map.Entry<Integer, String> entry : manufacturersMap.entrySet()){
op开发者_开发百科tion = new SelectItem(entry.getKey(),entry.getValue());
manufacturers.add(option);
}
}
return manufacturers;
}
public void setManufacturers(List<SelectItem> l){
manufacturers = l;
}
public List<SelectItem> getProducts(){
if(products == null){
SelectItem option;
products = new ArrayList<SelectItem>();
if(selectedPlan != null){
PMTQueryUtil pqu = new PMTQueryUtil();
Map<Integer, String> productsMap = pqu.getProducts();
for(Map.Entry<Integer, String> entry : productsMap.entrySet()){
option = new SelectItem(entry.getKey(),entry.getValue());
products.add(option);
}
}
}
return products;
}
public void setProducts(List<SelectItem> l){
products = l;
}
}
JSP fragment
<h:selectOneListbox id="manufacturerList"
value="#{ProductsBean.selectedManufacturer}"
size="10">
<f:selectItems value="#{ProductsBean.manufacturers}" />
</h:selectOneListbox>
<h:selectOneListbox id="productList"
value="#{PendingPlansBean.selectedProduct}"
size="10">
<f:selectItems binding="#{ProductsBean.products}" />
</h:selectOneListbox>
<f:selectItems binding="#{ProductsBean.products}" />
You've mistakenly used the binding
attribute instead of value
. The binding attribute is generally only used to bind the control instances to beans. This is probably the source of the exception because it is expecting the type UIComponent and getting List<SelectItems>
.
<managed-property>
<property-name>manufacturers</property-name>
<property-class>java.util.ArrayList</property-class>
<value>#{manufacturers}</value>
</managed-property>
Managed properties are a form of dependency injection. By defining the property above, you tell the JSF framework to resolve #{manufacturers}
and set it via setManufacturers
when the ProductBean
is instantiated. At best, this is harmless code that does nothing because there's no variable called manufacturers
in any of the scopes; but this mistake may lead to bugs further down the line.
精彩评论