primefaces4.0基本教程以及增删改查
最近试着用了用primefaces4.0,准备写一个基本的增删改查以及分页程序,但在写的过程中发现了很多问题,本想通过百度、谷歌解决,但无奈中文资料非常少,笔者在坑中不停的打滚,终于完成了一个有着基本功能的,还能看的过去的demo,想和大家一起分享一下,并希望能帮上和我一样陷入primefaces坑中的人。代码是仓促完成的,难免会有些缺点,还希望大家多多交流。http://www.mkyong.com/tutorials/jsf-2-0-tutorials/这个网站给了我非常大的帮助,在此表示严重感谢。
先来介绍一下primefaces吧,谈到primefaces,就要说到jsf了,jsf全称java server faces,简单来说就是一个Web 应用程序的新标准 Java 框架,而primeaces就是其中的一个实现,界面还是非常华丽的(笔者的意思是不大需要美工了),让笔者立刻想到了ExtJs...
接下来进入正题,先说说primefaces的基本环境配置
一、环境配置
先到官方网站https://javaserverfaces.java.net/下载2.2.4版的jsf ,primefaces是基于它的,然后去http://www.primefaces.org/downloads.html下载primefaces-4.0.jar,还需要jstl.jar和standard.jar包,最后加上类似数据库连接等别的jar包,lib目录下就完成了。
再看web.xml,需要加入以下代码:
<servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping>
然后编写一个传统的helloworld程序来测试环境是否配置成功
show.xhtml
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui"> <h:head> </h:head> <p:editor value=“hello world” /> </html>
打开浏览器,输入http://localhost:<端口号>/<项目名称>/faces/show.xhtml,如果看到如下结果,说明基本环境已经部署成功。
这里要注意个问题,就是<h:head></h:head>一定要加上,否则primefaces不会渲染它,笔者曾被这个坑稍微折磨了那么一会。。
二、分页查询
假设有如下实体类
PublicInfo.java
package test.entity; import java.io.Serializable; import java.util.Date; public class Info implements Serializable { private Integer id; private String title; private Date time; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Date getTime() { return time; } public void setTime(Date time) { this.time = time; } }
在数据库中有一个与之对应的表,字段分别是id(number),title(varchar),time(date),这三个字段类型可以代表绝大多数情况。这里要注意,实体类要实现Serializable接口,否则可能会出现一些小问题。这里顺便说一下吧,因为jsf框架的设计导致了前台与后台的联系十分密切,所以,需要与前台交互的类一般都要实现Serializable接口。
primefaces内提供了一个类LazyDataModel,只要继承这个类,并实现它的三个方法,我们的后台分页就已经完成一半了,代码如下:
LazyInfoDataModel.java
package test.bean; import java.util.Iterator; import java.util.List; import java.util.Map; import org.primefaces.model.LazyDataModel; import org.primefaces.model.SortOrder; import test.entity.Info; public class LazyInfoDataModel extends LazyDataModel<Info> { private List<Info> list; public LazyInfoDataModel(){} @Override public List<Info> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,String> filters) { //这个方法不光可以实现分页,也可以实现过滤与排序 /*我们暂时只实现简单的分页, first代表起始位置,pageSize代表查询数量,其他参数可以暂时不管,这两个参数就可以实现分页功能 要查询出数据与数量 */ //setRowCount(数量); //这个方法一定要执行! //list = 查询结果 return list; } @Override public Info getRowData(String rowKey) { for(Info info : list) { if(info.getId().toString().equals(rowKey)) { return info; } } return null; } @Override public Object getRowKey(Info info) { return info.getId(); } }
后台还需要最后一部分,这一部分是与前台密切相关的,这个类主要负责与前台进行数据的交互,以及实现一些业务逻辑,代码如下:
InfoBean.java
package test.bean; import java.io.Serializable; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import org.primefaces.model.LazyDataModel; import test.entity.Info; @ManagedBean(name="infoBean") @SessionScoped public class InfoBean implements Serializable { private LazyDataModel<Info> lazyModel = new LazyInfoDataModel(); public LazyDataModel<Info> getLazyModel() { return lazyModel; } public void setLazyModel(LazyDataModel<Info> lazyModel) { this.lazyModel = lazyModel; } }
这里还是要说明一下,@ManagedBean(name="infoBean")这个是jsf2的新特性,在jsf1中,需要写一个xml配置文件来配置,但jsf2取消了xml配置文件,改为使用注解。其中的name属性指定的值是在前台页面中这个类的别名,一会大家可以在前台页面的代码中看到。@SessionScoped表示作用域,其他的作用域还有@RequestScoped、@ViewScoped,看看名字大家就知道是怎么回事了,本教程的业务逻辑需要session作用域,所以就使用@SessionScoped了。
最后是前台部分了,直接上代码:
show.xhtml
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui"> <h:head> </h:head> <h:form id="form1"> <p:dataTable var="info" value="#{infoBean.lazyModel}" paginator="true" rows="10" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15" id="infoTable" lazy="true"> <p:column headerText="id"> <h:outputText value="#{info.id}" /> </p:column> <p:column headerText="title"> <h:outputText value="#{info.title}" /> </p:column> <p:column headerText="time"> <h:outputText value="#{info.time}"> <f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" /> </h:outputText> </p:column> </p:dataTable> </h:form> </html>
又要做一些说明了,大家注意看这个value="#{infoBean.lazyModel}",其中的infobean就是前面InfoBean的@ManagedBean(name="infoBean")中的属性,var="info",这个大家应该一看就知道了。还有时间处理<f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" /> ,也要注意一下,然后就可以看看页面效果了。
以上就是分页查询的基本代码(好吧,测试数据是挺坑爹的...),大家可以看到,primefaces已经帮我们实现了分页,还可以指定每页显示的条数,大家快试试吧。
大家还可以参考官方的例子http://www.primefaces.org/showcase/ui/datatableLazy.jsf,在官方的例子中,还提供了过滤与排序的demo。
三、添加
我们准备添加一个add按钮,弹出一个输入框,让用户输入要添加的信息,保存后刷新页面。
先上修改后的前台页面代码:
show.xhtml
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui"> <h:head> </h:head> <h:form id="form1"> <p:dataTable var="info" value="#{infoBean.lazyModel}" paginator="true" rows="10" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15" id="infoTable" lazy="true"> <p:column headerText="id"> <h:outputText value="#{info.id}" /> </p:column> <p:column headerText="title"> <h:outputText value="#{info.title}" /> </p:column> <p:column headerText="time"> <h:outputText value="#{info.time}"> <f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" /> </h:outputText> </p:column> </p:dataTable> </h:form> <p:commandButton value="add" onclick="PF('addDialog').show()" /> <p:dialog header="add" widgetVar="addDialog" modal="true"> <h:form id="form3"> <h:panelGrid columns="2" cellpadding="5" id="addPanel"> <p:outputLabel value="id" /> <p:inputText value="#{infoBean.selected.id}" /> <p:outputLabel value="title" /> <p:inputText value="#{infoBean.selected.title}" /> <p:outputLabel value="time" /> <p:inputMask value="#{infoBean.selected.time}" mask="9999-99-99 99:99:99"> <f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" /> </p:inputMask> <p:commandButton value="confirm" oncomplete="PF('addDialog').hide()" actionListener="#{infoBean.add}" update=":form1:infoTable,form3" /> </h:panelGrid> </h:form> </p:dialog> </html>
又到了说明的时间了,与之前的show.xhtml相比,我们增加了一个<p:commandButton />和一个<p:dialog />,注意一下这里<p:inputMask value="#{infoBean.selected.time}" mask="9999-99-99 99:99:99">,我们使用了一个<p:inputMask />标签,这个标签可以限制用户的输入格式,这样转成date就更加方便了。还有一点需要注意,我们用了一个id为form3的<h:form />标签将需要提交的信息包在里面,一定要加上这个form,否则会有一些不大好解释的问题,笔者之前又被这个问题小折磨了会。。还要注意actionListener="#{infoBean.add}"和update=":form1:infoTable,form3",通过actionListener可以看到jsf中前台与后台是如何进行交互的,update表示执行完这个表单提交需要更新的地方,我们要更新查询页面,也要更新自己的form3,否则当用户再想增加新内容时,看到已经填好了信息,他会不会迷惑呢。。。
再是后台代码:
InfoBean.java
package test.bean; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import javax.faces.event.ActionEvent; import org.primefaces.model.LazyDataModel;import test.entity.Info; @ManagedBean(name="infoBean") @SessionScoped public class InfoBean implements Serializable { private LazyDataModel<Info> lazyModel = new LazyInfoDataModel(); private Info selected = new Info(); public void add(ActionEvent e) { //在这里写上向数据库保存的内容的代码,selected就是前台传来的待保存信息 selected = new Info(); //由于是session作用域,会存在脏数据的问题,我们清除它 } public LazyDataModel<Info> getLazyModel() { return lazyModel; } public void setLazyModel(LazyDataModel<Info> lazyModel) { this.lazyModel = lazyModel; } public Info getSelected() { return selected; } public void setSelected(Info selected) { this.selected = selected; } }
我们增加了一个selected和一个add方法,具体的对应关系和前台的参照一下
然后是效果图:
我们添加一个id为2的数据,提交
可以看到,id为2的那条数据已经添加进去了。
四、更新&删除
前台代码:
show.xhtml
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui" xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"> <h:head> </h:head> <h:form id="form1"> <p:dataTable var="info" value="#{infoBean.lazyModel}" paginator="true" rows="10" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15" id="infoTable" lazy="true"> <p:column headerText="id"> <h:outputText value="#{info.id}" /> </p:column> <p:column headerText="title"> <h:outputText value="#{info.title}" /> </p:column> <p:column headerText="time"> <h:outputText value="#{info.time}"> <f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" /> </h:outputText> </p:column> <p:column headerText=""> <p:commandButton value="delete"> <p:ajax event="click" listener="#{infoBean.select(info)}" oncomplete="PF('delDialog').show()" /> </p:commandButton> <p:commandButton value="update"> <p:ajax event="click" listener="#{infoBean.select(info)}" oncomplete="PF('updateDialog').show()" update=":form4" /> </p:commandButton> </p:column> </p:dataTable> </h:form> <p:dialog header="Are you sure?" widgetVar="delDialog" modal="true"> <h:form id="form2"> <h:panelGrid columns="2" cellpadding="5" id="addPanel"> <f:facet name="facet1"> <p:outputLabel value="Are you sure?" /> </f:facet> <p:commandButton value="yes" actionListener="#{infoBean.delete}" update=":form1:infoTable" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" oncomplete="PF('delDialog').hide()" /> <p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" oncomplete="PF('delDialog').hide()" /> </h:panelGrid> </h:form> </p:dialog> <p:commandButton value="add" onclick="PF('addDialog').show()" /> <p:dialog header="add" widgetVar="addDialog" modal="true"> <h:form id="form3"> <h:panelGrid columns="2" cellpadding="5" id="addPanel"> <p:outputLabel value="id" /> <p:inputText value="#{infoBean.selected.id}" /> <p:outputLabel value="title" /> <p:inputText value="#{infoBean.selected.title}" /> <p:outputLabel value="time" /> <p:inputMask value="#{infoBean.selected.time}" mask="9999-99-99 99:99:99"> <f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" /> </p:inputMask> <p:commandButton value="confirm" oncomplete="PF('addDialog').hide()" actionListener="#{infoBean.add}" update=":form1:infoTable,form3" /> </h:panelGrid> </h:form> </p:dialog> <p:dialog header="update" widgetVar="updateDialog" modal="true"> <h:form id="form4"> <h:panelGrid columns="2" cellpadding="5" id="addPanel"> <p:outputLabel value="id" /> <p:inputText value="#{infoBean.selected.id}" readonly="true" /> <p:outputLabel value="title" /> <p:inputText value="#{infoBean.selected.title}" /> <p:outputLabel value="time" /> <p:inputMask value="#{infoBean.selected.time}" mask="9999-99-99 99:99:99"> <f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" /> </p:inputMask> <p:commandButton value="confirm" oncomplete="PF('updateDialog').hide()" actionListener="#{infoBean.update}" update=":form1:infoTable" /> </h:panelGrid> </h:form> </p:dialog> </html>
注意一下这里<p:ajax event="click" listener="#{infoBean.select(info)}" oncomplete="PF('updateDialog').show()" update=":form4" />,这里是笔者在做这个项目的过程中遇到的最头疼的问题,这里涉及到一个传值的问题,原来笔者是这么写的<p:commandButton actionListener="#{infoBean.select(info)}" oncomplete="PF('updateDialog').show()" />,而且primefaces官方demo也是这么写,但笔者在测试时发现,这样写会先调用oncomplete,显示dialog,然后再调用actionListener,在dialog显示的时候后台还没有接受到值,所以会报错,估计是笔者运气好吧,想到了一个这样的方法,可以解决这个问题。
后台代码
InfoBean.java
package test.bean; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import javax.faces.event.ActionEvent; import org.primefaces.model.LazyDataModel;import test.entity.Info; @ManagedBean(name="infoBean") @SessionScoped public class InfoBean implements Serializable { private LazyDataModel<Info> lazyModel = new LazyInfoDataModel(); private Info selected = new Info(); public void select(Info selected) { this.selected = selected; } public void add(ActionEvent e) { //jdbc selected = new Info(); } public void update(ActionEvent e) { //jdbc selected = new Info(); } public void delete(ActionEvent e) { //jdbc selected = new Info(); } public LazyDataModel<Info> getLazyModel() { return lazyModel; } public void setLazyModel(LazyDataModel<Info> lazyModel) { this.lazyModel = lazyModel; } public Info getSelected() { return selected; } public void setSelected(Info selected) { this.selected = selected; } }
primefaces4.0基本教程以及增删改查的更多相关文章
- Yii2.0高级框架数据库增删改查的一些操作(转)
yii2.0框架是PHP开发的一个比较高效率的框架,集合了作者的大量心血,下面通过用户为例给大家详解yii2.0高级框架数据库增删改查的一些操作 --------------------------- ...
- Yii2.0高级框架数据库增删改查的一些操作
yii2.0框架是PHP开发的一个比较高效率的框架,集合了作者的大量心血,下面通过用户为例给大家详解yii2.0高级框架数据库增删改查的一些操作 --------------------------- ...
- Asp.Net WebApi学习教程之增删改查
webapi简介 在asp.net中,创建一个HTTP服务,有很多方案,以前用ashx,一般处理程序(HttpHandler),现在可以用webapi 微软的web api是在vs2012上的mvc4 ...
- java springboot整合zookeeper入门教程(增删改查)
java springboot整合zookeeper增删改查入门教程 zookeeper的安装与集群搭建参考:https://www.cnblogs.com/zwcry/p/10272506.html ...
- [py]flask从0到1-模板/增删改查
flask知识点 1.后端渲染html到前端 render_template 2.后端获取前端数据 request.args.get 3.前端获取后端数据 模板 4.警示消息 flash {{ get ...
- NetCore2.0 RozarPage自动生成增删改查
原文链接:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/web-api-help-pages-using-swagger 上面的只是原文 ...
- SQLite 入门教程(四)增删改查,有讲究 (转)
转于: SQLite 入门教程(四)增删改查,有讲究 一.插入数据 INSERT INTO 表(列...) VALUES(值...) 根据前面几篇的内容,我们可以很轻送的创建一个数据表,并向其中插入一 ...
- SSH(Struts 2.3.31 + Spring 4.1.6 + Hibernate 5.0.12 + Ajax)框架整合实现简单的增删改查(包含分页,Ajax 无刷新验证该用户是否存在)
软件152 余建强 该文将以员工.部门两表带领大家进入SSH的整合教程: 源码下载:http://download.csdn.net/detail/qq_35318576/9877235 SSH 整合 ...
- 微软Connect教程系列--自动生成增删改查页面工具介绍(二)
本章课程描述了vs2015的三个特点,其中主要将描述在vs2015下面,使用命令自动生成增删改查界面,具体如下: 1.web.config文件不在存在,用config.json替代,以适应支撑vs的插 ...
随机推荐
- JEECMS中返回列表跳转的几种方式
1.返回的不是当前类 <span class="tools pull-right"> <button class="btn btn-info" ...
- js-JavaScript高级程序设计学习笔记2
第四章 变量.作用域和内存问题 1.ES变量包含两种不同数据类型的值--基本类型值(5种基本数据类型)和引用类型值(保存在内存中的对象,所有引用类型值都是Object的实例) 2.只能给引用类型值动态 ...
- 【BZOJ-2937】建造酿酒厂 前缀和 + 展环为链 + 乱搞
2937: [Poi2000]建造酿酒厂 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 70 Solved: 24[Submit][Status][D ...
- Android数据存储-通过SharedPreferences实现记住密码的操作
在Android中登陆中,为了实现用户的方便,往往需要根据用户的需要进行记住密码的操作,所以,在Android数据存储中SharedPreferences恰恰可以实现这一点 下面,小编将带领大家通过S ...
- xcoj1062
题意:给出一个闭合折线上的一堆点(不按顺序),然后再给一个点P,要求判断P是否在闭合折线内 sol attempt1:一开始觉得是个模板题的,后来发现不对劲: 给出的点并不按照顺序.这样模板大法就不行 ...
- .net 运用YUI相关的dll压缩js (按照自己的规则,想想都觉得强大和有趣)
写在前面 不管是做前端的还是做后台的,不管是懂javaScript的还是不太懂JavaScript的人,我想都或多或想的知道些许js压缩对于页面性能提升的效应吧. 之前老喜欢用在线压缩工具去压缩js, ...
- ubuntu14.04安装GoldenDict
1. 软件商店搜索goldendict安装或者$ sudo apt-get install goldendict 2. 配置网页翻译源 编辑-->词典--->网站选项卡,点击添加 以下是有 ...
- ubuntu默认防火墙
ubuntu 9.10默认的是UFW防火墙,已经支持界面操作了.在命令行运行ufw命令就可以看到提示的一系列可进行的操作. 最简单的一个操作:sudo ufw status可检查防火墙的状态,我的返回 ...
- js009-客户端检测
js009-客户端检测 本章内容: 1.使用能力检测 2.用户代理检测的历史 3.选择检测方式 一般不使用客户端检测. 9.1 能力检测 也称特性检测.基本模式如下: if(object.proper ...
- socket传数据并记录到文件中
最近在新项目中要通过socket传一些数据,下面是程序: 功能: 将客户端发送的json数据写入到日志文件中,如果数据不是json的,丢弃. 程序如下: #!/usr/bin/env python # ...