在s2sh架构中利用pager-taglib、interceptor和ThreadLocal 根据用户需求显示进行分页,在此将实现一个根据用户在下拉列表用选择每页将要显示多少行进行分页,在实现时我将数据结果集的获取与分页参数的设置独立分开,所以在我们页面请求提交到的Action类中并看不到分页参数的踪迹...
声明: pager-taglib组件默认的每页显示数目为10,相应的属性是maxPageItems="10",因此我可以将用户自己的显示行数放在session内,并将其赋值给maxPageItems就可以实现用户自己的分页类型。例如httpRequest.getSession().setAttribute("ps", 10);然后maxPageItems="ps".
关于pager-taglib标签的参数及使用请参考pager-tablib分页http://lzh166.iteye.com/blog/616715
下面开始贴代码了
首先下载pager-taglib-2.0.war ,地址
http://jsptags.com/tags/navigation/pager/download.jsp,然后将lib下面的包lib下的jar包放到自己项目的lib下面。
1、实体类Organization 属性:id、name、description,在这里就不在多描述了。
2、封装类BaseService
public class BaseService extends HibernateDaoSupport {
@Resource //将setSessionFactory()进行重构,注入spring中的sessionFactory
public void setSuperSessionFactory(SessionFactory sessionFactory){
super.setSessionFactory(sessionFactory);
}
public List searchByPage(String hql){
return searchByPage(hql, null);
}
public List searchByPage(String hql ,Object param){
return searchByPage(hql,new Object[]{param} ,PagerContext.getOffset(), PagerContext.getPagesize());
}
public List searchByPage(String hql ,Object[] params){
//查询总记录数
String countHql = this.getCountHql(hql);
Query query = this.getSession().createQuery(countHql);
if(params !=null && params.length>0){
for(int i=0;i<params.length;i++){
query.setParameter(i, params[i]);
}
}
int totals = ((Long)(query.uniqueResult())).intValue();
//将总记录数放到ThreadLocal局部变量中
PagerContext.setTotals(totals);
//查询分页结果集数据
query = this.getSession().createQuery(hql);
if(params !=null && params.length>0){
for(int i=0;i<params.length;i++){
query.setParameter(i, params[i]);
}
}
query.setFirstResult(PagerContext.getOffset()); //通过PagerContext得到offset
query.setMaxResults(PagerContext.getPagesize()); //通过PagerContext得到pagesize
List datas = query.list();
return datas;
}
/**
* 根据HQL查询语句,分析得到查询总记录数的查询语句
* 根据HQL语句,获得查找总记录数的HQL语句如:select .... from ...
* 转换为:select count(*) from ....
* @param hql
* @return
*/
private String getCountHql(String hql){
//取得from的位置
int index = hql.toLowerCase().indexOf("from");
if(index != -1){
return "select count(*)"+ hql.substring(index);
}
throw new RuntimeException("无效的查询语句【"+hql+"】");
}
}
3、业务逻辑类:orgServiceImpl
@Service("orgService") //纳入Spring容器管理
public class OrgServiceImpl extends BaseService{
public List<Organization> searchOrgs(int parentId) {
String hql = "from Organization o where o.parent.id is null";
if(parentId !=0){
hql = "from Organization o where o.parent.id="+parentId;
}
return this.searchByPage(hql);
}
}
4、分页数据类:PagerContext类 利用ThreadLocal方式实现分页传值
//用于得到每页个显示数和用于查询的首记录数以及总记录数
public class PagerContext {
//ThreadLocal 线程局部变量,就是为每一个使用该变量的线程提供一个局部的变量值的副本,每个线程都可以独立的改变该线程的变量副本,
//而不会和其它线程的副本冲突,也就是在分页的页面中用户可以根据自己的设置任意改变每页的显示的记录数而不会影响到其他用户浏览数据显示
private static ThreadLocal<Integer> offset = new ThreadLocal<Integer>();//用于query.setFirstResult(offset)
private static ThreadLocal<Integer> pagesize = new ThreadLocal<Integer>();//每页显示的行数用于 query.setMaxResults(pagesize);
private static ThreadLocal<Integer> totals = new ThreadLocal<Integer>(); //总记录数
public static void setOffset(int value){
offset.set(value); //设置当前线程局部变量offset的值
}
public static int getOffset(){
Integer os = (Integer)offset.get();
if(os ==null){
return 0;
}
return os; //返回当前线程所对应的线程局部变量offset
}
public static void setPagesize(int value){
pagesize.set(value); //设置当前线程局部变量pagesize的值
}
public static int getPagesize(){
Integer ps = (Integer)pagesize.get();
if(ps == null){
return Integer.MAX_VALUE; //如果没有设置pagesize则显示一页
}
return ps; 返回当前线程所对应的线程局部变量pagesize
}
public static void setTotals(int value){
ServletActionContext.getRequest().setAttribute("totals", value);
totals.set(value); //设置当前线程局部变量totals的值
}
public static int getTotals(){
Integer ts = (Integer)totals.get();
if(ts == null){
return 0;
}
return ts; //返回当前线程所对应的线程局部变量totals
}
public static void remove(){
//将当前线程局部变量的值删除,目的是为了减少内存的占用,
offset.remove(); //清除为每个用户分配的副本
pagesize.remove();
totals.remove();
}
}
5、分页拦截器类:PagerInterceptor
public class PagerInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
//将请求得到的分页参数设置到ThreadLocal的局部变量中
PagerContext.setTotals(getTotals());
PagerContext.setOffset(getOffset());
PagerContext.setPagesize(getPagesize());
try {
return invocation.invoke();
} finally {
//需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,
PagerContext.remove(); //所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
}
}
private int getTotals() {
int totals = PagerContext.getTotals(); //从PagerContext 中取得总记录数
return totals;
}
private int getOffset(){
int offset = 0;
try { //从request请求中获取当前页查询的首记录数
offset = Integer.parseInt(ServletActionContext.getRequest().getParameter("pager.offset"));//得到标签自己计算出的pager.offset
} catch (Exception e) {
}
return offset;
}
private int getPagesize(){
//从页面中请求中,获取用户设置每页显示记录数,取得pagesize参数的值
String ps = ServletActionContext.getRequest().getParameter("pagesize");
if(ps != null){
try {
Integer pagesize = Integer.parseInt(ps);
ServletActionContext.getRequest().getSession().setAttribute("ps",pagesize);
} catch (Exception e) {
}
}
//从session中获取pagesize参数的值
Integer pagesize = (Integer)ServletActionContext.getRequest().getSession().getAttribute("ps");
//如果为空,则表示用户没有设置就则显示默认每页显示10行,并将其放入session,以便在显示页面赋值给maxPageItems使用
if(pagesize == null){
ServletActionContext.getRequest().getSession().setAttribute("ps", 10);
return 10;
}
return pagesize;
}
}
6、页面请求类:orgAction
@Controller("orgAction")
@Scope("prototype")
public class OrgAction implements ModelDriven {
private Organization org = new Organization();
private int pid; //父机构ID
@Resource
private OrgService orgService;
/**
* 显示列表
*/
public String execute(){
//保持父机构的父亲的ID,为返回留用
int ppid=0;
if(pid!=0){
Organization o = this.orgService.find(pid);
if(o.getParent()!=null){
ppid = o.getParent().getId();
}
}
ActionContext.getContext().put("ppid", ppid);
//获取分页数据后,将其放到PagerModel模型中
List<Organization> orgs = orgService.searchOrgs(pid);
ActionContext.getContext().put("orgs", orgs);
return "default";
}
public void preUpdate(int id) {
//根据ID加载机构信息,并将信息赋值给我们的模型,
//等待ModelDrivenInterceptor去将取出模型中的数据如不为空则压入值栈中
//ModelDrivenInterceptor a = new ModelDrivenInterceptor();
org = this.orgService.find(id);
}
public Organization getModel() {
return org;
}
public Organization getOrg() {
return org;
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
}
7、显示页面:list.jsp 部分代码
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="pg" uri="http://jsptags.com/tags/navigation/pager"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
...
<script type="text/javascript">
function selectPagesize(field){
document.location.href = document.all.firstpageurl.href + "&pagesize="+field.value;//得到用户从下拉列表选择的每页显示的行数,并刷新到转到首页
}
</script>
....
<s:if test="!#orgs.isEmpty">
<s:iterator value="#orgs">
<tr bgcolor="#EFF3F7" class="TableBody1" onmouseover="this.bgColor = '#DEE7FF';" onmouseout="this.bgColor='#EFF3F7';">
<td align="center" vAlign="center"><s:property value="id"/></td>
<td align="center" vAlign="center"><a href="org.action?pid=<s:property value="id"/>"><s:property value="name"/></a></td>
<td align="center" vAlign="center"><s:property value="sn"/></td>
<td align="center" vAlign="center"><s:property value="parent.name"/></td>
<td align="center" vAlign="center"><a href="javascript:openWin('org!updateInput.action?id=<s:property value="id"/>','updateorg',600,200);">更新</a>
<a href="javascript:del('org!del.action?id=<s:property value="id"/>')">删除</a></td>
</tr>
</s:iterator>
</s:if>
<!-- 在列表数据为空的时候,要显示的提示信息 -->
<s:else>
<tr>
<td colspan="7" align="center" bgcolor="#EFF3F7" class="TableBody1" onmouseover="this.bgColor = '#DEE7FF';" onmouseout="this.bgColor='#EFF3F7';">
没有找到相应的记录
</td>
</tr>
</s:else>
.....
<!-- 分页导航条设置 -->
<pg:pager url="org.action" items="${totals}" export="currentPageNumber=pageNumber" maxPageItems="${ps}"> <!-- ${ps}是得到session范围内的每页显示的行数 -->
<pg:param name="pid"/>
<pg:first>
<a href="${pageUrl}" id="firstpageurl">首页</a><!-- 为选择列表后请求提供链接 -->
</pg:first>
<pg:prev>
<a href="${pageUrl}" >前页</a>
</pg:prev>
<pg:pages>
<c:choose>
<c:when test="${currentPageNumber eq pageNumber}">
<font color="red">${pageNumber}</font> <!-- 当前页号不显示链接 -->
</c:when>
<c:otherwise>
<a href="${pageUrl}">${pageNumber}</a>
</c:otherwise>
</c:choose>
</pg:pages>
<pg:next>
<a href="${pageUrl}">后页</a>
</pg:next>
<pg:last>
<a href="${pageUrl}">尾页</a>
</pg:last>
</pg:pager>
<!-- 用户选择每页显示行数下拉列表 -->
每页显示
<select name="pagesize" onchange="go(this);" >
<c:forEach begin="5" end="50" step="5" var="i">
<option value="${i}" <c:if test="${ps eq i }">selected</c:if> >${i}</option>
</c:forEach>
</select>行
分页导航图:
- 大小: 4.2 KB
分享到:
相关推荐
在JavaWeb开发中,分页是常见的功能,用于在大量数据中进行导航。"pager-taglib"是一个专门用于实现分页效果的标签库,它提供了一种方便的方式来在JSP页面上显示分页链接,而无需编写大量的HTML和Java代码。下面我们...
- 使用分页标签:在JSP中,可以使用`<pager:page>`标签来显示分页链接,`<pager:previous>`和`<pager:next>`标签分别用于上一页和下一页的链接。 例如: ```jsp <pager:page rowsPerPage="10" totalRows="${...
**Pager-taglib页面分页示例** 在Java Web开发中,数据量大的时候,分页显示是非常必要的。Pager-taglib就是一个专门用于实现页面分页功能的JSP标签库,它可以帮助开发者快速、方便地在页面上展示分页链接。本项目...
`pager-taglib`通过接收服务器端的数据总数和每页显示的数量,动态生成分页链接,用户点击不同页码时,发送请求获取对应页的数据。 2. **标签库的引入** 在JSP页面中,首先需要引入`pager-taglib`的TLD文件,通常...
3. **自定义标签**:在`pager-taglib`中,可能包含如`<pager:page>`、`<pager:prev>`、`<pager:next>`等标签,分别用于显示当前页、上一页和下一页的链接,以及分页导航的其他元素。 4. **属性和参数**:这些自定义...
pager-taglib 是个很好的jsp分页标签,使用它结合jstl可以实现灵活的分页导航功能。在实际的开发中post方式的提交比较常见,本人做了一个比较通用的基于post方式的一个应用。主要实现一下功能: 1.添加输入跳转、每...
`pager-taglib`是Java Web开发中常用的分页标签库,它简化了在JSP页面上实现分页功能的过程。这个标签库通常与Spring MVC、Struts2等框架结合使用,提供了一种声明式的方式来展示数据分页。下面将详细解释`pager-...
在`pager-taglib`标签库中,包含了处理分页所需的各个标签,如显示总页数、当前页、上一页、下一页等,这些标签可以直接插入到JSP页面中,通过传入必要的参数,如当前页码、总记录数等,就能自动计算并生成分页链接...
Pager-taglib适用于任何需要分页显示数据的场景,如论坛、电商产品列表、新闻列表等。它的易用性和灵活性使得开发者能快速实现高效且美观的分页效果。 7. **最佳实践** - 保持每页的数据量适中,以提供良好的用户...
1. **引入库**:首先,你需要在项目的类路径中添加`pager-taglib-2.0.jar` 文件。这可以通过将文件放入WEB-INF/lib目录,或者在Maven或Gradle等构建工具中声明依赖来完成。 2. **配置TLD**:在Web应用的WEB-INF目录...
在这个“pager-taglib分页例子”中,我们将探讨如何使用`pager-taglib`进行高效且简洁的分页实现。 首先,`pager-taglib`提供了几个预定义的标签,如`<pg:pager>`、`<pg:firstPage>`、`<pg:lastPage>`、`...
Displaytag和Pager-taglib是两个在Java Web开发中常用的分页库,主要用于处理大量数据的显示,提升用户体验,减轻服务器压力。这两个库都是基于JSP标签库(Tag Library)实现的,可以方便地集成到Spring、Struts等...
在`tld`文件中,可以设置标签的默认属性,比如每页显示的记录数、总页数计算方式等。在实际使用时,可以通过标签的属性进行个性化配置,以适应不同的需求。 5. **与后端交互** `pager-taglib`标签通常需要与后端...
- **用户体验**:合理设置每页显示的条数,提供足够的导航选项(如上一页、下一页、跳转至指定页等),以提升用户操作的便捷性和满意度。 综上所述,`pager-taglib`为JSP项目中的分页功能提供了一套简单而强大的...
1. **简单易用**:"pager-taglib-2.0" 提供了直观的标签接口,开发者只需在JSP页面中插入相应的标签,即可快速设置分页功能。 2. **高度可定制化**:这个库支持多种样式和布局配置,可以根据项目需求定制分页按钮的...
在Java服务器页面(JSP)开发中,分页是一个常见的需求,特别是在处理大量数据时,为了提高用户体验,通常会将数据分成多个页面显示。`pager-taglib`是JSP的一个标签库,它提供了方便的分页功能,简化了开发者的工作...
分页是Web应用程序中常见的功能,它允许用户在大量数据中进行导航,通常用于数据库查询结果的展示,如电商网站的商品列表或论坛的帖子列表。 **描述分析:**"pager-taglib-2.0 JSP分页组件 包括jar包和安装使用说明...
4. 使用PagerTaglib库:在JSP页面中,引入PagerTaglib库,并设置相关属性,如总记录数、每页记录数、当前页码等。例如: ```jsp <%@ taglib prefix="pg" uri="http://pager.taglib.com/pager"%> <pg:pager total=...