由于primefaces在国内使用的并不是太多,因此,国内对jsf做系统、详细的介绍的资料很少,即使有一些资料,也仅仅是对国外资料的简单翻译或者是仅仅讲表面现象(皮毛而已),它们的语句甚至还是错误的,很可能会误导使用者。
相对来说,看国内的那些仅仅是翻译过来的文章或书籍不如直接看国外的官方文档或资料来的实在,在我讲述jsf页面中如何使用js调用后台bean方法之前,先给大家说几个国外的资料。在primefaces官方网站上,你可以搜索到几乎所有你需要的东西,primefaces官网为:http://www.primefaces.org/showcase/index.xhtml 如过觉得自己英语不好的童鞋,可以前往primefaces国内镜像网站查阅资料: http://www.primefaces.cn/ ,只是国内的这个网站正在翻译中,有些东西还不完善;如果有想细致的了解primefaces的朋友,还可以下载primefaces的官方文档,最新的官方文档为5.2,全英文,我在这里给大家提供我下载好的primefaces官方文档:http://pan.baidu.com/s/1mg3i9Ry ,在这个文档里你可以通过他们的示例来组合出来很多有趣的东西。另外我在淘宝上发现了Primefaces官方的JSF框架,官方售价300RMB,淘宝售价才五元,大家可以前去学习:https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-12555052969.2.nPXnNz&id=523880497056
目前对于很多国内软件开发人员来说,JSF+weld(CDI)+hibernate的框架开发模式着实有相当大的问题,其中最主要的问题就是,国内相关的资料很少,出现了问题也只能去国外找解决办法。
作者也是深受其害,所以现在我养成了一个习惯,就是把自己辛苦很久才解决了的问题一一贴出来,供广大的被JSF所折麽java开发的朋友们来参照自己的问题解决。
下面以实例来表述我对此问题的解决方法,本文的实例的主要业务是动态显示数据库中的数据,页面上的数据的表现形式为DataTable,对页面数据的操作有增删改查,均为通过复选框达到目的。
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:pe="http://primefaces.org/ui/extensions" template="/templates/temp_nwc.xhtml"> <ui:define name="content"> <h:form id="form"> <p:toolbar id="toolBar" style="margin-top:6px;"> <f:facet name="left"> <p:commandButton value="修改" actionListener="#{dataPvgRoleTypeManager.arrangementRoles}" oncomplete="PF('allPvgRoleType').show()" icon="ui-icon-edit" disabled="#{dataPvgRoleTypeManager.selectedDataPvgRoleTypes.size()!=1 or dataPvgRoleTypeManager.selectedDataPvgRoleTypes==null}" update="form" /> <p:commandButton value="删除" action="#{dataPvgRoleTypeManager.delete}" icon="ui-icon-delete" disabled="#{dataPvgRoleTypeManager.selectedDataPvgRoleTypes.size()==0 or dataPvgRoleTypeManager.selectedDataPvgRoleTypes==null}" update="form" /> <p:commandButton value="添加" onclick="PF('allPvgRoleType').show()" ajax="true" icon="ui-icon-new" /> </f:facet> </p:toolbar> <p:dataTable id="pvgRoleTypTable" widgetVar="pvgTypes" var="pvgType" value="#{dataPvgRoleTypeManager.searchResults}" rowKey="#{pvgType.id}" selection="#{dataPvgRoleTypeManager.selectedDataPvgRoleTypes}" editable="true" resizableColumns="true" filteredValue="#{dataPvgRoleTypeManager.filteredDataPvgRoleType}" paginator="true" rows="20" rowsPerPageTemplate="10,15,20,25,30" paginatorPosition="bottom" styleClass="cleanHeader" style="width:100%"> <f:facet name="header"> <table style="padding: 0px; margin: 0px;"> <TR> <TD style="border: 0px; text-align: left;"><h:outputText value="规则类型列表" /></TD> <TD style="border: 0px;"><p:outputPanel style="text-align:right;width:100%;"> <h:outputText value="搜索:" /> <p:inputText id="globalFilter" onkeyup="PF('inTable').filter()" placeholder="Enter keyword" style="width:150px;" /> </p:outputPanel></TD> </TR> </table> </f:facet> <p:column style="width:3%"> <p:rowToggler /> </p:column> <p:ajax event="rowSelectCheckbox" ajax="true" immediate="true" update=":form:toolBar" process="@this" /> <p:ajax event="rowUnselectCheckbox" ajax="true" immediate="true" update=":form:toolBar" process="@this" /> <p:column style="width:16px;text-align:center" selectionMode="multiple" /> <p:column sortBy="#{pvgType.pvg_type_name}" filterBy="#{pvgType.pvg_type_name}" headerText="类型名称" filterMatchMode="contains"> <h:outputText value="#{pvgType.pvg_type_name}"/> </p:column> <p:column sortBy="#{pvgType.note}" filterBy="#{pvgType.note}" headerText="说明" filterMatchMode="contains"> <h:outputText value="#{pvgType.note}"/> </p:column> <!-- 规则详情 --> <p:rowExpansion> <p:panelGrid columns="2" columnClasses="label,value" style="width:300px" id="detailPanel"> <p:outputLabel value="id" /> <h:outputText value="#{pvgType.id}" /> <p:outputLabel value="创建人ID:" /> <h:outputText value="#{pvgType.createID}" /> <p:outputLabel value="创建时间:" /> <h:outputText value="#{pvgType.createTime}" /> <p:outputLabel value="最后修改人ID:" /> <h:outputText value="#{pvgType.lastModifyID}" /> <p:outputLabel value="最后修改时间:" /> <h:outputText value="#{pvgType.lastModifyTime}" /> </p:panelGrid> </p:rowExpansion> </p:dataTable> <!-- 添加规则条件 --> <p:dialog header="添加规则条件" widgetVar="allPvgRoleType" modal="false" id="allPvgRoleType"> <h:panelGrid columns="2" id="allPvgRoleTypePanel"> <p:outputLabel for="pvgTypeName" value="条件:" /> <p:inputText id="pvgTypeName" value="#{dataPvgRoleTypeManager.selecteddataPvgRoleType.pvg_type_name}" /> <p:outputLabel for="pvgTypeNote" value="备注" /> <p:inputTextarea rows="6" cols="33" id="pvgTypeNote" value="#{dataPvgRoleTypeManager.selecteddataPvgRoleType.note}" /> </h:panelGrid> <p:commandButton value="添加" oncomplete="PF('allPvgRoleType').hide()" actionListener="#{dataPvgRoleTypeManager.save}" update="pvgRoleTypTable"/> <p:commandButton value="取消" onclick="PF('allPvgRoleType').hide()" /> </p:dialog> </h:form> </ui:define> </ui:composition>
import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.inject.Named; import org.hibernate.Session; import org.hibernate.Transaction; import zuccess.zcplt.basic.HibernateUtil; import zuccess.zcplt.basic.privilege.dao.DataPvgRoleTypeDao; import zuccess.zcplt.basic.privilege.model.DataPvgRoleType; import zuccess.zcplt.basic.util.FacesUtils; @Named("dataPvgRoleTypeManager") @javax.faces.view.ViewScoped public class DataPvgRoleTypeManager implements Serializable { private static final long serialVersionUID = -8447565166018378408L; private DataPvgRoleTypeDao dataPvgRoleTypeDao = new DataPvgRoleTypeDao(); // private List<DataPvgRoleType> searchResults = PvgRoleTypeService.getInstance().getDataPvgRoleTypes(); private DataPvgRoleType selecteddataPvgRoleType = new DataPvgRoleType(); private List<DataPvgRoleType> searchResults = new ArrayList<DataPvgRoleType>(); private List<DataPvgRoleType> selectedDataPvgRoleTypes; private List<DataPvgRoleType> filteredDataPvgRoleType; private Session session = HibernateUtil.getSession(); @SuppressWarnings("unchecked") public void search(){ this.searchResults = dataPvgRoleTypeDao.findAll(); } public void arrangementPvgRoleTypes(){ System.out.println("测试整合"); selecteddataPvgRoleType=selectedDataPvgRoleTypes.get(0); } public void delete(){ try { Transaction tx = session.beginTransaction(); int count = selectedDataPvgRoleTypes.size(); for (int i = 0; i < count; i++) { DataPvgRoleType dataPvgRoleType = selectedDataPvgRoleTypes.get(i); session.delete(dataPvgRoleType); searchResults.remove(dataPvgRoleType); if (i % 20 == 0) { session.flush(); session.clear(); } } tx.commit(); System.out.println("删除成功"); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } } public void save(){ Transaction tx = session.beginTransaction(); try { if (selecteddataPvgRoleType.getCreateTime() != null) { // 修改的操作 selecteddataPvgRoleType.setLastModifyTime(new Date()); selecteddataPvgRoleType.setLastModifyID(FacesUtils.getCurrentUser().getId()); session.update(session.merge(selecteddataPvgRoleType)); } else { // 新增的操作 selecteddataPvgRoleType.setCreateTime(new Date()); selecteddataPvgRoleType.setCreateID(FacesUtils.getCurrentUser().getId()); session.save(session.merge(selecteddataPvgRoleType)); searchResults.add(selecteddataPvgRoleType); } tx.commit(); } catch (RuntimeException re) { tx.rollback(); re.printStackTrace(); } } /** set and get **/ public DataPvgRoleType getSelecteddataPvgRoleType() { return selecteddataPvgRoleType; } public void setSelecteddataPvgRoleType(DataPvgRoleType selecteddataPvgRoleType) { this.selecteddataPvgRoleType = selecteddataPvgRoleType; } public List<DataPvgRoleType> getSearchResults() { if(searchResults.size()==0) search(); return searchResults; } public void setSearchResults(List<DataPvgRoleType> searchResults) { this.searchResults = searchResults; } public List<DataPvgRoleType> getSelectedDataPvgRoleTypes() { return selectedDataPvgRoleTypes; } public void setSelectedDataPvgRoleTypes( List<DataPvgRoleType> selectedDataPvgRoleTypes) { this.selectedDataPvgRoleTypes = selectedDataPvgRoleTypes; } public List<DataPvgRoleType> getFilteredDataPvgRoleType() { return filteredDataPvgRoleType; } public void setFilteredDataPvgRoleType( List<DataPvgRoleType> filteredDataPvgRoleType) { this.filteredDataPvgRoleType = filteredDataPvgRoleType; } }
@Entity @Table(name="ZCPLT_PVG_TYPE") public class DataPvgRoleType extends BaseInfo implements Serializable{ /** * */ private static final long serialVersionUID = -3029188820180895304L; private String pvg_type_name; private String note; private String id; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getNote() { return note; } public void setNote(String note) { this.note = note; } public String getPvg_type_name() { return pvg_type_name; } public void setPvg_type_name(String pvg_type_name) { this.pvg_type_name = pvg_type_name; } }
import java.io.Serializable; import java.util.List; import org.hibernate.Query; import org.jfree.util.Log; import zuccess.zcplt.basic.privilege.model.DataPvgRoleType; public class DataPvgRoleTypeDao extends HibernateBaseDao implements Serializable { /** * */ private static final long serialVersionUID = -679651584173196788L; @SuppressWarnings("rawtypes") public List findAll(){ Log.debug("finding all DataPvgRoleType instance"); try { String queryString = "from DataPvgRoleType"; Query queryObject = getSession().createQuery(queryString); return queryObject.list(); } catch (RuntimeException re) { Log.error("find all failed", re); throw re; } } }
以上就是全部的代码,其运行效果如下:
由于我的目的是当在页面 上进行增删改查后希望它能够及时自己刷新,因此我在bean 的save()方法里面添加了一个语句:searchResults.add(selecteddataPvgRoleType);
但是呢,当我运行程序时,完成新增的操作后,回显的过程中就会出现下面的错误提示:
DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled.
官方给出的解决方法有两个:
1.Adding rowKey, selection and selectionMode attributes to dataTable
2.Implementing SelectableDataModel interface and extending a DataModel like ListDataModel for filling the dataTable
第二种的解决方法很麻烦,有兴趣的朋友可去primefaces官网查看相关的demo,这里不再赘述
第一种的解决方法是最简单的,只需在dataTable中添加属性,rowKey={xxxx.xxx}和selectionMode="multiple"即可,当然 多选和单选的selectionMode=""值是不同的,请大家注意。
朋友们的平常的问题,只需第一中解决方法即可解决报错的问题,如果涉及到页面刷新的问题,请接着往下看。
但是我插看了一下我的代码,返现并不缺少这些组件,那么,它到底是为什么呢?
我细致的分析了一下我的bean中的业务逻辑和需求,我发现了一个问题,我在页面中的
的rowKey属性的值为:rowKey="#{pvgType.id}",而在bean类中的的将新增用户添加到searchResults的过程中,这个新增的用户并没有主键信息ID,那么将其添加到searchResults后,在页面上回显searchResults必然会因为这个新加的对象没用ID而不能被rowKey="#{pvgType.id}"所识别,它自然就报错了。
明白了这个问题的根节后,修改就容易多了,只需将rowKey="#{pvgType.id}"的id修改为这个新增的用户对象中不为null的任意属性即可,例如:rowKey="#{pvgType.pvg_type_name}",然后再次运行程序,OK,没有任何问题了。