JSF Backing Bean属性未保存且commandLink无法正常运行

时间:2013-11-09 18:34:30

标签: jsf java-ee primefaces war glassfish-4

今天有两个问题,

我有这种代码的和平:

catalog.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"
      xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
    <h:head>
        <f:facet name="first">
            <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        </f:facet>
        <title>booXtore - Catalog</title>
        <h:outputStylesheet library="css" name="main.css"/>
        <h:outputStylesheet library="css" name="font-awesome.css"/>
        <!--[if lt IE 9]>
            <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
            <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
        <![endif]-->
    </h:head>
    <h:body>
        <ui:include src="/WEB-INF/includes/navbar.xhtml"/>
        <div id="wrap">

            <div id="main" class="container clear-top">

                <ol class="breadcrumb">
                    <li class="active">Catalogue</li>
                </ol>

                <h:form >
                    <div class="row">
                        <div class="col-md-6">
                            <p:inputText id="searchBar" type="search" styleClass="form-control" placeholder="Recherche" value="#{searchProviderBean.search}"/>
                        </div>

                        <div class="col-md-4">
                            <h:selectOneMenu styleClass="form-control" value="#{searchProviderBean.searchCategory}">
                                <f:selectItem itemValue="#{searchProviderBean.defaultCategorySearch}" 
                                              itemLabel="#{searchProviderBean.defaultCategorySearch.name}"/>
                                <c:forEach items="#{searchProviderBean.categories}" var="category">
                                    <f:selectItem itemValue="#{category}"
                                                  itemLabel="#{category.name}"/>
                                </c:forEach>
                            </h:selectOneMenu>
                        </div>

                        <div class="col-md-2">
                            <h:commandLink class="btn btn-info" value="Rechercher" action="#{searchProviderBean.launchSearch}"/>
                        </div>
                    </div>
                </h:form>
            </div>
        </div>
    </h:body>
</hthml

SearchProviderBean:

package com.booXtore;

import com.booXtore.domain.Books;
import com.booXtore.domain.Categories;
import com.booXtore.service.BooksFacadeLocal;
import com.booXtore.service.CategoriesFacadeLocal;
import java.io.Serializable;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

@ManagedBean
@ViewScoped
public class SearchProviderBean implements Serializable {

    @EJB
    private BooksFacadeLocal bFL;
    @EJB
    private CategoriesFacadeLocal cFL;

    private String search;
    private Categories searchCategory;

    /**
     * Creates a new instance of SearchProviderBean
     */
    public SearchProviderBean() {
    }

    public List<Categories> getCategories() {
        List<Categories> result = cFL.findAll();

        return result;
    }

    public Categories getSearchCategory() {
        FacesContext fc = FacesContext.getCurrentInstance();
        for(Categories cat : this.cFL.findAll())
        {
            if(cat.getName().equalsIgnoreCase(getParam(fc, "category")))
            {
                this.searchCategory = cat;
            }
        }
        return this.searchCategory;
    }

    public void setSearchCategory(Categories searchCategory) {
        this.searchCategory = searchCategory;
    }

    public String launchSearch() {
        String cat = "";
        if(!this.searchCategory.getName().equalsIgnoreCase("Toutes Catégories"))
        {
            cat = "category=" + this.searchCategory.getName();
        }
        return "/catalog.xhtml?faces-redirect=true&search=" + search + cat;

    }

    public String getSearch() {
        FacesContext fc = FacesContext.getCurrentInstance();
        String searchParam = getParam(fc , "search");
        if(searchParam != null)
        {
            this.search = searchParam;
        }

        return search;
    }

    public void setSearch(String search) {
        this.search = search;
    }

    public Categories getDefaultCategorySearch()
    {
        Categories def = new Categories();
        def.setName("Toutes Catégories");
        return def;
    }

    public List<Books> getSearchResults() {
        return null;
    }

    public List<Books> getAllBooks()
    {
        return this.bFL.findAll();
    }

    private String getParam(FacesContext fc, String paramName)
    {
        return fc.getExternalContext().getRequestParameterMap().get(paramName);
    }

}

然后问题:

  • 永远不会调用方法setSearch(String search)setSearchCategory(Categories searchCategory)(通过断点检查)

  • 永远不会调用commandLink操作方法(通过return语句上的断点检查),只重新加载页面。

我试图将commandLink更改为commandButton:除了样式更改之外没有任何效果 我尝试将@ViewScoped注释更改为@SessionScoped但没有效果

编辑:

由于整个页面的大小和'因为我是jsf的新手,我没有看到页面底部显示的错误消息,告诉我转换{{的值时出错1}} for null converter

1 个答案:

答案 0 :(得分:0)

找到答案。

我只需要一个转换器用于我的对象。 现在,我的班级提供了一个ToString()方法,只允许显示我的自定义对象。

据我所知,问题在于保存对象的状态。 Je JSF组件试图保存我的对象的文本表示。遗憾的是,属性的​​set方法没有在参数中使用类型String,而是使用类型类型。

我必须创建一个Converter类,它允许我自动将我的lbject转换为另一个(text&lt; - &gt; object)。

以下是我使用的代码:

package com.booXtore.converters;

import com.booXtore.domain.Categories;
import com.booXtore.service.CategoriesFacadeLocal;
import javax.ejb.EJB;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

/*The converter class has to be annotated and identified*/
@FacesConverter("com.booXtore.converters.CategoriesConverter")
public class CategoriesConverter implements Converter{

    @EJB
    private CategoriesFacadeLocal cFL;

    /*The method who will return an object based on the string passed by the JSF component*/
    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if((value != null) || (Integer.parseInt(value) == -1))
        {
            Integer id = Integer.parseInt(value);
            return cFL.find(id);
        }
        Categories cat = new Categories();
        cat.setName("Toutes Catégories");
        return cat;
    }

    /*THe method wich will return the String that will represent the object*/
    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        Categories cat = (Categories)value;
        if(cat.getName().equals("Toutes Catégories"))
        {
            return "-1";
        }
        else
        {
            return cat.getId().toString();
        }
    }

}

我还必须在<f:converter converteedId="com.booXtore.converters.CategoriesConverter"/>组件中添加<h:selectOneMenu>来注册转换器。

对于一个可能更清晰的教程和一个完整的例子,这个网站对我帮助很大:Custom Converter in JSF