第一步:webroot/web-inf下的str.tld文件

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib> <!-- 自定义库标签的根 -->
<tlibversion>1.2</tlibversion> <!-- 版本号 -->
<jspversion>1.1</jspversion> <!-- JSP版本号 -->
<shortname>stu</shortname> <!-- prefix="stu"标签名称-->
<uri>StudentTags</uri> <!-- uri="StudentTags" 外界导入标签时,认识的名字,很重要。--> <tag>
<name>selectAll</name> <!-- 标签名称 -->
<tagclass>com.bjsxt.sxf.tag.SeclectAllSt</tagclass> <!-- 对应的java类的全路径 -->
</tag> <!-- 有属性的标签,可以有多个属性 <attribute>并列 -->
<tag>
<name>selectBySex</name> <!-- 标签名称 -->
<tagclass>com.bjsxt.sxf.tag.SeclectStBySex</tagclass>
<attribute> <!-- 对应标签的属性。 -->
<name>sex</name>
<required>true</required> <!-- 是必需写的属性,即没有写属性标签不能被正常使用 -->
</attribute>
</tag>
<!-- 按班级学生id查询出班级集合,存放到属性var指定的变量中,然后利用s标签的迭代标签,将var指定的变量存放的学生集合遍历出来 -->
<tag>
<name>selectByClassId</name> <!-- 标签名称 -->
<tagclass>com.bjsxt.sxf.tag.MyTag</tagclass> <!-- 对应的java类的全路径 -->
<body-content>JSP</body-content><!-- 如果不需要标签体则设置empty,反之设定jsp,内部可以运行jsp所有的语法 -->
<attribute>
<name>classId</name><!--指定属性名 和标签java类一致-->
<required>true</required><!--该属性是否是必须,如果非必须没设置则为空。 -->
<rtexprvalue>true</rtexprvalue><!-- 该属性能不能动态使用表达式为该属性赋值 true可以 false不可以 使用脚本和EL表达式来获取动态的值 -->
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>num</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
<!-- 自定义的myif标签 -->
<tag>
<name>myif</name>
<tagclass>com.bjsxt.sxf.tag.MyIfTag</tagclass>
<bodycontent>JSP</bodycontent>
<attribute>
<name>flag</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>condition</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- 自定义的myelseif标签 -->
<tag>
<name>myelseif</name>
<tagclass>com.bjsxt.sxf.tag.MyElseIfTag</tagclass>
<bodycontent>JSP</bodycontent>
<attribute>
<name>flag</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>condition</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- 自定义的myelse标签 -->
<tag>
<name>myelse</name>
<tagclass>com.bjsxt.sxf.tag.MyElseTag</tagclass>
<bodycontent>JSP</bodycontent>
</tag>
<!-- 自定义的分页标签 -->
<tag>
<name>page</name>
<tagclass>com.bjsxt.sxf.tag.PageTag</tagclass>
<body-content>empty</body-content><!-- 如果不需要标签体则设置empty,反之设定jsp,内部可以运行jsp所有的语法 -->
<attribute>
<name>pageNo</name><!--当前页码数-->
<required>false</required><!--该属性是否是必须,如果非必须没设置则为空。 -->
<rtexprvalue>true</rtexprvalue><!-- 该属性能不能动态使用表达式为该属性赋值 true可以 false不可以 使用脚本和EL表达式来获取动态的值 -->
<type>int</type>
</attribute>
<attribute>
<name>pageSize</name><!--当前页码数-->
<required>false</required><!--该属性是否是必须,如果非必须没设置则为空。 -->
<rtexprvalue>true</rtexprvalue><!-- 该属性能不能动态使用表达式为该属性赋值 true可以 false不可以 使用脚本和EL表达式来获取动态的值 -->
<type>int</type>
</attribute>
<attribute>
<name>rowCount</name><!--当前页码数-->
<required>false</required><!--该属性是否是必须,如果非必须没设置则为空。 -->
<rtexprvalue>true</rtexprvalue><!-- 该属性能不能动态使用表达式为该属性赋值 true可以 false不可以 使用脚本和EL表达式来获取动态的值 -->
<type>int</type>
</attribute>
</tag> </taglib>

第二步:pageTag.java标签类和PageComponent.java标签逻辑类

 package com.bjsxt.sxf.tag;

 import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ComponentTagSupport; import com.bjsxt.sxf.tag.compant.PageComponent;
import com.opensymphony.xwork2.util.ValueStack;
/**
* 自定义分页标签的标签类
* @ClassName: PageTag
* @Description: TODO(这里用一句话描述这个类的作用)
* @author 尚晓飞
* @date 2014-10-23 下午4:39:01
*
*/
public class PageTag extends ComponentTagSupport{ //标签中属性,往这传值(本示例没有用属性传值,而是在标签逻辑类中通过获取值栈,获取分页标签所需的对象和请求地址)
private Integer pageNo;//当前页
private Integer pageSize;//每页显示记录数
private Integer rowCount;//总记录数 @Override
public Component getBean(ValueStack arg0, HttpServletRequest arg1,
HttpServletResponse arg2) { return new PageComponent(arg0, arg1, arg2);
} @Override
protected void populateParams() {
super.populateParams();
PageComponent pageComponent=(PageComponent) getComponent();
pageComponent.setPageNo(pageNo);
pageComponent.setPageSize(pageSize);
pageComponent.setRowCount(rowCount); } public Integer getPageNo() {
return pageNo;
} public void setPageNo(Integer pageNo) {
this.pageNo = pageNo;
} public Integer getPageSize() {
return pageSize;
} public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
} public Integer getRowCount() {
return rowCount;
} public void setRowCount(Integer rowCount) {
this.rowCount = rowCount;
} } package com.bjsxt.sxf.tag.compant; import java.io.IOException;
import java.io.Writer;
import java.util.List;
import java.util.Map; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.struts2.StrutsStatics;
import org.apache.struts2.components.Component;
import org.apache.struts2.dispatcher.StrutsRequestWrapper; import com.bjsxt.sxf.util.Page;
import com.opensymphony.xwork2.util.ValueStack; /**
* 分页标签集合类。
* 本示例直接从值栈中得到本次请求的分页对象,以及请求action的地址信息。所以本示例没有采用jsp页面标签属性,往后台传递信息
*
* 也可以通过标签往后台传递值。则需要建立一个所有action都会继承的pageAction,每次请求,页码当前页,总记录数,每页显示记录数,以及查询条件等等,都要在pageAction中建立
* 相应属性。而且所有的请求地址的参数都必须与pageAction中的属性对应。jsp页面上自定义分页标签的属性从本次请求的值栈中取出页码当前页,总记录数,每页显示记录数,然后传递给
* pageTag的标签类,标签类在传递给pageComponent中,然后再逻辑类中编写分页代码(本示例没用这种情况,但标签建立了相应的属性)
*
*
* @ClassName: PageComponent
* @Description: TODO(这里用一句话描述这个类的作用)
* @author 尚晓飞
* @date 2014-10-23 下午4:20:17
*
*/
public class PageComponent extends Component {
private Integer pageNo;//当前页
private Integer pageSize;//页面显示记录数
private Integer rowCount;//总记录数
private String reqUrl;//标签所在页面的请求地址url public PageComponent(ValueStack stack,HttpServletRequest request,HttpServletResponse response) {
super(stack); } @Override
public boolean end(Writer writer, String body) {
// TODO Auto-generated method stub
return super.end(writer, body);
} @Override
public boolean start(Writer writer) { //获取值栈
ValueStack stack=this.getStack();
Map cont= this.getStack().getContext();
StrutsRequestWrapper req=(StrutsRequestWrapper)cont.get(StrutsStatics.HTTP_REQUEST);
//获取请求action的地址
//示例:/Struts2HibernateSpring/StudentAction!queryStudent
String url=(String)req.getAttribute("javax.servlet.forward.request_uri");
//获取请求参数的地址
//示例:seachName=%E5%B0%9A%E6%99%93%E9%A3%9E&pageNo=1
//如果不存在请求参数,则返回是null 也就是说paramString是null
String paramString=(String) req.getAttribute("javax.servlet.forward.query_string");
//从值栈中获取分页对
Page page=(Page) stack.findValue("page");
//获取页码传递的参数 此处每页显示记录数为后台默认控制,所以不用拼接pageSize(每页显示多少条记录)的参数传递。
//将页码数参数,放在url的最后
String newUrl="";
if(paramString!=null&&!paramString.equals("")){
//有请求参数
Integer index=paramString.lastIndexOf("pageNo");
paramString=paramString.substring(0,index);
newUrl=url+"?"+paramString; }else{
newUrl=url+"?";
} //拼接分页代码
StringBuffer sb=new StringBuffer(""); /**
* 简单的页面分页html代码
* <table border="2">
<tr>
<td>总共页数<td>
<td>10</td>
<td>当前页数</td>
<td>2</td>
<td>》》</td>
</tr>
<tr>
<td>首页</td>
<td>上一页</td>
<td>1,<b style="color: red;">2</b>,3,4,5</td>
<td>下一页</td>
<td>尾页</td>
</tr>
</table>
*/
sb.append("<table border=\"2\">");
sb.append("<tr>");
sb.append("<td>总共页数</td>");
sb.append("<td>"+page.getPageCount()+"</td>");
sb.append("<td>当前页数</td>");
sb.append("<td>"+page.getPageNum()+"</td>");
sb.append("<td>》》</td>");
sb.append("</tr>");
sb.append("<tr>");
sb.append("<td><a href=\""+newUrl+"pageNo="+page.getFirstPage()+"\">首页</a></td>");
sb.append("<td><a href=\""+newUrl+"pageNo="+page.getPreviousPage()+"\">上一页</a></td>");
List<Integer> pageList=page.getPageList();
if(pageList!=null&&pageList.size()>0){
sb.append("<td>");
//有页码列表
for(int i=0;i<pageList.size();i++){
Integer num=pageList.get(i);
Integer pageNum=page.getPageNum();
if(pageNum==num){
sb.append("<a href=\""+newUrl+"pageNo="+num+"\"><b style=\"color: red;\">"+num+"</b></a>,");
}else{
sb.append("<a href=\""+newUrl+"pageNo="+num+"\">"+num+"</a>,");
} }
sb.append("</td>");
}else{
sb.append("<td>0</td>");
}
sb.append("<td><a href=\""+newUrl+"pageNo="+page.getNextPage()+"\">下一页</a></td>");
sb.append("<td><a href=\""+newUrl+"pageNo="+page.getLastPage()+"\">尾页</a></td>");
sb.append("</tr>");
sb.append("</table>"); try {
writer.write(sb.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return false;
} public Integer getPageNo() {
return pageNo;
} public void setPageNo(Integer pageNo) {
this.pageNo = pageNo;
} public Integer getPageSize() {
return pageSize;
} public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
} public Integer getRowCount() {
return rowCount;
} public void setRowCount(Integer rowCount) {
this.rowCount = rowCount;
} public String getReqUrl() {
return reqUrl;
} public void setReqUrl(String reqUrl) {
this.reqUrl = reqUrl;
} }

第三步:jsp页面测试

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<%@ taglib uri="StudentTags" prefix="stu" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'list.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
<h1>学生表</h1>
<table border="2">
<tr>
<td>id</td>
<td>姓名</td>
<td>性别</td>
<td>班级</td>
</tr>
<s:iterator value="#root.list" var="stu">
<tr>
<td><s:property value="#stu.id"/></td>
<td><s:property value="#stu.name"/></td>
<td><s:property value="#stu.sex"/></td>
<td><s:property value="#stu.classRoom.name"/></td>
</tr>
</s:iterator>
</table>
<h1>分页列表</h1>
<!-- 自定义的分页标签,本示例没有用自定义标签中的属性往标签类中传递值 -->
<stu:page/> </body>
</html>

第四步:显示效果

Struts2自定义标签4自定义分页标签的更多相关文章

  1. Struts2自定义标签2自定义一个按班级id查询出该班级下的学生,存放进值栈,并遍历出来。

    Struts2自定义标签的流程概念: (1)需要两个类:标签类(继承相应的tag类),基本类(继承Component).标签类专门负责从客户端取得用户输入的一些属性,这个普通的jsp自定义标签一样,取 ...

  2. Java自定义分页标签的实现

    主要字段含义: 页号 pagaNo页面大小 pageSize总记录条数 recordCount计算本次一共分多少页 myPageSize页号显示开始 start 页号显示结束 end PageTag需 ...

  3. SSH自定义分页标签

    本文参考文章:http://blog.csdn.net/qjyong/article/details/3240303 一.标签处理类: package cn.conris.sys.form; impo ...

  4. 自定义分页标签,并使分页标签能获得url中的参数

    如题,要实现一个分页功能,其次,要让分页标签“智能一点”,在分页时能自动带上url后面的参数 <tag> <description>分页标签</description&g ...

  5. Django 中的自定义分页标签

    目录结构: 1.在应用下,migrations的同级目录创建templatetags目录(主要两个文件,包含__init__.py) 2.创建分页标签(pagetag.py) #!/usr/bin/e ...

  6. JavaWeb学习记录(十九)——jstl自定义标签库之传统标签

    一.传统标签 (1)JSP引擎将遇到自定义标签时,首先创建标签处理器类的实例对象,然后按照JSP规范定义的通信规则依次调用它的方法. public void setPageContext(PageCo ...

  7. 剖析html对标准标签和自定义标签闭合与不闭合渲染问题

    昨天在修改去年写的系统的时候无意中看到了当时写的一个利用标准标签未闭合在单元格内把整个单元格颜色渲染成红色的效果,如下: 当时的问题是从后台返回来的是个int整数而%是写在页面上的如图 这 时候就出现 ...

  8. dedecms利用memberlist标签调用自定义会员模型的会员信息

    [摘要]本文讲一下dedecms如何利用memberlist标签调用自定义会员模型的会员信息. dedecms利用memberlist标签调用自定义会员模型的会员信息,这个问题找了很久,官方论坛提问过 ...

  9. 一、JSP标签介绍,自定义标签

    一.JSP标签介绍 1. 标签库有什么作用 自定义标签库是一种优秀的表现层技术,之前介绍的MVC模式,我们使用jsp作为表现层,但是jsp语法嵌套在html页面,美工还是很难直接参与开发,并且jsp脚 ...

随机推荐

  1. jquery1.7.2的源码分析(三)$.Deferred

    例子的详细讲解 Filter Resolve var filterResolve = function() { var defer = $.Deferred(), filtered = defer.t ...

  2. Linux Red hat修改主机名

    步骤一:修改etc/hosts文件内容为 [root@kypt01 /]# cd etc[root@kypt01 etc]# cat hosts127.0.0.1 localhost kypt01 l ...

  3. 分页-pagination

    需先引入jQuery,再引入pagination组件 <script src="jquery.js"></script> <script src=&q ...

  4. js 设置回车事件

    document.onkeydown=function(event){ var e = event || window.event || arguments.callee.caller.argumen ...

  5. iOS:关于获取网络类型和运营商信息

    目录 1. 获取运营商网络类型 2. 获取运营商信息 返回目录 1. 获取运营商网络类型 Apple的Reachability Sample看起来不错,但是只可以判断是否连接到互联网和是否连接Wifi ...

  6. 图论专题训练1-D(K步最短路,矩阵连乘)

    题目链接 /* *题目大意: *求出从i到j,刚好经过k条边的最短路; * *矩阵乘法的应用之一(国家队论文): *矩阵乘法不满足交换律,矩阵乘法满足结合律; *给定一个有向图,问从A点恰好走k步(允 ...

  7. S2 深入.NET和C#编程 三:使用集合组织相关数据

    三:使用集合组织相关数据 集合概念: ArrayList:非常类似于数组,也有人称他为数组的列表.ArrayList可以动态维护,数组的容量是固定的 和数组类似,ArrayList中存储的是数据成为元 ...

  8. TP框架自带的正则验证的规则

    thinkphp框架里面自带有很多自动验证的规则,下面是框架自带的正则验证的规则,官方的说明文档里面没有这么多,所以记下来,以备使用. view sourceprint? 01 static $reg ...

  9. PHPStorm 最新版 去掉参数提示 parameter name hints

    最新的phpstorm有个默认开启的参数名和类型提示功能, 这对于开发有很大的帮助,但是对于有些同学来说,刚开始可鞥不是很习惯,所以就需要把他给关闭. 在 配置面板中搜索 parameter name ...

  10. 小甲鱼Python第二十讲课后习题---021

    笔记: 1.lambda表达式的作用: 1)Python写一些执行脚本时,使用lambda就可以省下定义函数的过程,比如说我们只是需要写一个简单的脚本来管理服务器时间,我们就不需要专门定义一个函数然后 ...