如果我需要让Integer运行查询,那么JSF Converter的正确实现是什么? (我应该使用其他界面)

时间:2010-06-17 16:36:59

标签: jsf ejb

这是我的代码:

List.xhmtl

<h:selectOneMenu value="#{produtosController.items}">
    <f:selectItems value="#{produtosController.itemsAvailableSelectOne}"/>
</h:selectOneMenu>
<h:commandButton action="#{produtosController.createByCodigos}" value="Buscar" />

我的控制器类具有内置的转换器实现

@ManagedBean (name="produtosController")
@SessionScoped
public class ProdutosController {

    private Produtos current;
    private DataModel items = null;
    @EJB private controladores.ProdutosFacade ejbFacade;
    private PaginationHelper pagination;
    private int selectedItemIndex;

    public ProdutosController() {
    }

    public Produtos getSelected() {
        if (current == null) {
            current = new Produtos();
            selectedItemIndex = -1;
        }
        return current;
    }

    private ProdutosFacade getFacade() {
        return ejbFacade;
    }

    public PaginationHelper getPagination() {
        if (pagination == null) {
            pagination = new PaginationHelper(10) {

                @Override
                public int getItemsCount() {
                    return getFacade().count();
                }

                @Override
                public DataModel createPageDataModel() {
                    return new ListDataModel(getFacade().findRange(new int[]{getPageFirstItem(), getPageFirstItem()+getPageSize()}));
                }
            };
        }
        return pagination;
    }

    public String prepareList() {
        recreateModel();
        return "List";
    }

    public String prepareView() {
        current = (Produtos)getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "View";
    }

    public String prepareCreate() {
        current = new Produtos();
        selectedItemIndex = -1;
        return "Create";
    }

    public String create() {
        try {
            getFacade().create(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("ProdutosCreated"));
            return prepareCreate();
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }
    public String createByMarcas() {
        items = new ListDataModel(ejbFacade.findByMarcas(current.getIdMarca()));
        updateCurrentItem();
        return "List";
    }

    public String createByModelos() {
        items = new ListDataModel(ejbFacade.findByModelos(current.getIdModelo()));
        updateCurrentItem();
        return "List";
    }

    public String createByCodigos(){
        items = new ListDataModel(ejbFacade.findByCodigo(current.getCodigo()));
        updateCurrentItem();
        return "List";
    }

    public String prepareEdit() {
        current = (Produtos)getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "Edit";
    }

    public String update() {
        try {
            getFacade().edit(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("ProdutosUpdated"));
            return "View";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String destroy() {
        current = (Produtos)getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        performDestroy();
        recreateModel();
        return "List";
    }

    public String destroyAndView() {
        performDestroy();
        recreateModel();
        updateCurrentItem();
        if (selectedItemIndex >= 0) {
            return "View";
        } else {
            // all items were removed - go back to list
            recreateModel();
            return "List";
        }
    }

    private void performDestroy() {
        try {
            getFacade().remove(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("ProdutosDeleted"));
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
        }
    }

    private void updateCurrentItem() {
        int count = getFacade().count();
        if (selectedItemIndex >= count) {
            // selected index cannot be bigger than number of items:
            selectedItemIndex = count-1;
            // go to previous page if last page disappeared:
            if (pagination.getPageFirstItem() >= count) {
                pagination.previousPage();
            }
        }
        if (selectedItemIndex >= 0) {
            current = getFacade().findRange(new int[]{selectedItemIndex, selectedItemIndex+1}).get(0);
        }
    }

    public DataModel getItems() {
        if (items == null) {
            items = getPagination().createPageDataModel();
        }
        return items;
    }

    private void recreateModel() {
        items = null;
    }

    public String next() {
        getPagination().nextPage();
        recreateModel();
        return "List";
    }

    public String previous() {
        getPagination().previousPage();
        recreateModel();
        return "List";
    }

    public SelectItem[] getItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
    }

    public SelectItem[] getItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
    }

    @FacesConverter(forClass=Produtos.class)
    public static class ProdutosControllerConverter  implements Converter{

        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            ProdutosController controller = (ProdutosController)facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "produtosController");
            return controller.ejbFacade.find(getKey(value));
        }

        java.lang.Integer getKey(String value) {
            java.lang.Integer key;
            key = Integer.decode(value);
            return key;
        }

        String getStringKey(java.lang.Integer value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }

        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Produtos) {
                Produtos o = (Produtos) object;
                return getStringKey(o.getCodigo());
            } else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: "+ProdutosController.class.getName());
            }
        }

    }

}

和我的EJB

@Entity
@ViewScoped
@Table(name = "produtos")
@NamedQueries({
    @NamedQuery(name = "Produtos.findAll", query = "SELECT p FROM Produtos p"),
    @NamedQuery(name = "Produtos.findById", query = "SELECT p FROM Produtos p WHERE p.id = :id"),
    @NamedQuery(name = "Produtos.findByCodigo", query = "SELECT p FROM Produtos p WHERE p.codigo = :codigo"),
    @NamedQuery(name = "Produtos.findByDescripcion", query = "SELECT p FROM Produtos p WHERE p.descripcion = :descripcion"),
    @NamedQuery(name = "Produtos.findByImagen", query = "SELECT p FROM Produtos p WHERE p.imagen = :imagen"),
    @NamedQuery(name = "Produtos.findByMarcas", query="SELECT m FROM Produtos m WHERE m.idMarca.id = :idMarca"),
    @NamedQuery(name = "Produtos.findByModelos", query="SELECT m FROM Produtos m WHERE m.idModelo.id = :idModelo")})
public class Produtos implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Column(name = "codigo")
    private Integer codigo;
    @Column(name = "descripcion")
    private String descripcion;
    @Column(name = "imagen")
    private String imagen;
    @JoinColumn(name = "id_modelo", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private Modelos idModelo;
    @JoinColumn(name = "id_marca", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private Marcas idMarca;

    public Produtos() {
    }

    public Produtos(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getCodigo() {
        return codigo;
    }

    public void setCodigo(Integer codigo) {
        this.codigo = codigo;
    }

    public String getDescripcion() {
        return descripcion;
    }

    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }

    public String getImagen() {
        return imagen;
    }

    public void setImagen(String imagen) {
        this.imagen = imagen;
    }

    public Modelos getIdModelo() {
        return idModelo;
    }

    public void setIdModelo(Modelos idModelo) {
        this.idModelo = idModelo;
    }

    public Marcas getIdMarca() {
        return idMarca;
    }

    public void setIdMarca(Marcas idMarca) {
        this.idMarca = idMarca;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Produtos)) {
            return false;
        }
        Produtos other = (Produtos) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "" + codigo + "";
    }
}

1 个答案:

答案 0 :(得分:0)

抱歉,我没有密切关注您的代码。太多(乍一看)不相关的代码和几个过于本地化的名称,只会让事情变得混乱。至少有一个主要错误是您使用DataModel而非实际Product作为项目值。这毫无意义。

这是一个启动示例代码应如何在下拉列表中获得完美无缺的非标准类型。

XHTML:

<h:form>
    <h:selectOneMenu value="#{bean.selectedProduct}">
        <f:selectItems value="#{bean.selectProducts}" />
    </h:selectOneMenu>
    <h:commandButton value="Submit" action="#{bean.submit}" />
</h:form>

豆:

private Product selectedProduct; // +getter+setter
private List<SelectItem> selectProducts; // +getter

public Bean() {
    selectProducts = new ArrayList<SelectItem>();
    for (Product product : ejb.list()) {
        selectProducts.add(new SelectItem(product, product.getDescription()));
    }
}

public void submit() {
    System.out.println("Selected product: " + selectedProduct.getDescription());
}

ProductConverter:

public Object getAsObject(FacesContext context, UIComponent component, String value) {
    // Convert String to Integer and find Product by Integer ID.
    return ejb.find(Integer.valueOf(value));
}

public String getAsString(FacesContext context, UIComponent component, Object value) {
    // Convert Integer ID to String.
    return String.valueOf(((Product) value).getId());
}

或者,您也可以将f:selectItems与新的JSF 2.0 var属性一起使用,这样您就不需要将List<Product>从EJB转换为List<SelectItem>

XHTML:

<h:form>
    <h:selectOneMenu value="#{bean.selectedProduct}">
        <f:selectItems value="#{bean.selectProducts}" var="product" 
            itemValue="#{product}" itemLabel="#{product.description}" />
    </h:selectOneMenu>
    <h:commandButton value="Submit" action="#{bean.submit}" />
</h:form>

豆:

private Product selectedProduct; // +getter+setter
private List<Product> selectProducts; // +getter

public Bean() {
    selectProducts = ejb.list();
}

public void submit() {
    System.out.println("Selected product: " + selectedProduct.getDescription());
}

这仍然需要相同的ProductConverter


另见