第一步:webroot/web-inf下的str.tld文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> 3 <taglib> <!-- 自定义库标签的根 --> 4 <tlibversion>1.2</tlibversion> <!-- 版本号 --> 5 <jspversion>1.1</jspversion> <!-- JSP版本号 --> 6 <shortname>stu</shortname> <!-- prefix="stu"标签名称--> 7 <uri>StudentTags</uri> <!-- uri="StudentTags" 外界导入标签时,认识的名字,很重要。--> 8 9 <tag> 10 <name>selectAll</name> <!-- 标签名称 --> 11 <tagclass>com.bjsxt.sxf.tag.SeclectAllSt</tagclass> <!-- 对应的java类的全路径 --> 12 </tag> 13 14 <!-- 有属性的标签,可以有多个属性 <attribute>并列 --> 15 <tag> 16 <name>selectBySex</name> <!-- 标签名称 --> 17 <tagclass>com.bjsxt.sxf.tag.SeclectStBySex</tagclass> 18 <attribute> <!-- 对应标签的属性。 --> 19 <name>sex</name> 20 <required>true</required> <!-- 是必需写的属性,即没有写属性标签不能被正常使用 --> 21 </attribute> 22 </tag> 23 <!-- 按班级学生id查询出班级集合,存放到属性var指定的变量中,然后利用s标签的迭代标签,将var指定的变量存放的学生集合遍历出来 --> 24 <tag> 25 <name>selectByClassId</name> <!-- 标签名称 --> 26 <tagclass>com.bjsxt.sxf.tag.MyTag</tagclass> <!-- 对应的java类的全路径 --> 27 <body-content>JSP</body-content><!-- 如果不需要标签体则设置empty,反之设定jsp,内部可以运行jsp所有的语法 --> 28 <attribute> 29 <name>classId</name><!--指定属性名 和标签java类一致--> 30 <required>true</required><!--该属性是否是必须,如果非必须没设置则为空。 --> 31 <rtexprvalue>true</rtexprvalue><!-- 该属性能不能动态使用表达式为该属性赋值 true可以 false不可以 使用脚本和EL表达式来获取动态的值 --> 32 </attribute> 33 <attribute> 34 <name>var</name> 35 <required>true</required> 36 <rtexprvalue>false</rtexprvalue> 37 </attribute> 38 <attribute> 39 <name>num</name> 40 <required>false</required> 41 <rtexprvalue>false</rtexprvalue> 42 </attribute> 43 </tag> 44 <!-- 自定义的myif标签 --> 45 <tag> 46 <name>myif</name> 47 <tagclass>com.bjsxt.sxf.tag.MyIfTag</tagclass> 48 <bodycontent>JSP</bodycontent> 49 <attribute> 50 <name>flag</name> 51 <required>true</required> 52 <rtexprvalue>true</rtexprvalue> 53 </attribute> 54 <attribute> 55 <name>condition</name> 56 <required>true</required> 57 <rtexprvalue>true</rtexprvalue> 58 </attribute> 59 </tag> 60 <!-- 自定义的myelseif标签 --> 61 <tag> 62 <name>myelseif</name> 63 <tagclass>com.bjsxt.sxf.tag.MyElseIfTag</tagclass> 64 <bodycontent>JSP</bodycontent> 65 <attribute> 66 <name>flag</name> 67 <required>true</required> 68 <rtexprvalue>true</rtexprvalue> 69 </attribute> 70 <attribute> 71 <name>condition</name> 72 <required>true</required> 73 <rtexprvalue>true</rtexprvalue> 74 </attribute> 75 </tag> 76 <!-- 自定义的myelse标签 --> 77 <tag> 78 <name>myelse</name> 79 <tagclass>com.bjsxt.sxf.tag.MyElseTag</tagclass> 80 <bodycontent>JSP</bodycontent> 81 </tag> 82 <!-- 自定义的分页标签 --> 83 <tag> 84 <name>page</name> 85 <tagclass>com.bjsxt.sxf.tag.PageTag</tagclass> 86 <body-content>empty</body-content><!-- 如果不需要标签体则设置empty,反之设定jsp,内部可以运行jsp所有的语法 --> 87 <attribute> 88 <name>pageNo</name><!--当前页码数--> 89 <required>false</required><!--该属性是否是必须,如果非必须没设置则为空。 --> 90 <rtexprvalue>true</rtexprvalue><!-- 该属性能不能动态使用表达式为该属性赋值 true可以 false不可以 使用脚本和EL表达式来获取动态的值 --> 91 <type>int</type> 92 </attribute> 93 <attribute> 94 <name>pageSize</name><!--当前页码数--> 95 <required>false</required><!--该属性是否是必须,如果非必须没设置则为空。 --> 96 <rtexprvalue>true</rtexprvalue><!-- 该属性能不能动态使用表达式为该属性赋值 true可以 false不可以 使用脚本和EL表达式来获取动态的值 --> 97 <type>int</type> 98 </attribute> 99 <attribute> 100 <name>rowCount</name><!--当前页码数--> 101 <required>false</required><!--该属性是否是必须,如果非必须没设置则为空。 --> 102 <rtexprvalue>true</rtexprvalue><!-- 该属性能不能动态使用表达式为该属性赋值 true可以 false不可以 使用脚本和EL表达式来获取动态的值 --> 103 <type>int</type> 104 </attribute> 105 </tag> 106 107 108 </taglib>
第二步:pageTag.java标签类和PageComponent.java标签逻辑类
1 package com.bjsxt.sxf.tag; 2 3 import javax.servlet.http.HttpServletRequest; 4 import javax.servlet.http.HttpServletResponse; 5 6 import org.apache.struts2.components.Component; 7 import org.apache.struts2.views.jsp.ComponentTagSupport; 8 9 import com.bjsxt.sxf.tag.compant.PageComponent; 10 import com.opensymphony.xwork2.util.ValueStack; 11 /** 12 * 自定义分页标签的标签类 13 * @ClassName: PageTag 14 * @Description: TODO(这里用一句话描述这个类的作用) 15 * @author 尚晓飞 16 * @date 2014-10-23 下午4:39:01 17 * 18 */ 19 public class PageTag extends ComponentTagSupport{ 20 21 //标签中属性,往这传值(本示例没有用属性传值,而是在标签逻辑类中通过获取值栈,获取分页标签所需的对象和请求地址) 22 private Integer pageNo;//当前页 23 private Integer pageSize;//每页显示记录数 24 private Integer rowCount;//总记录数 25 26 @Override 27 public Component getBean(ValueStack arg0, HttpServletRequest arg1, 28 HttpServletResponse arg2) { 29 30 return new PageComponent(arg0, arg1, arg2); 31 } 32 33 @Override 34 protected void populateParams() { 35 super.populateParams(); 36 PageComponent pageComponent=(PageComponent) getComponent(); 37 pageComponent.setPageNo(pageNo); 38 pageComponent.setPageSize(pageSize); 39 pageComponent.setRowCount(rowCount); 40 41 } 42 43 public Integer getPageNo() { 44 return pageNo; 45 } 46 47 public void setPageNo(Integer pageNo) { 48 this.pageNo = pageNo; 49 } 50 51 public Integer getPageSize() { 52 return pageSize; 53 } 54 55 public void setPageSize(Integer pageSize) { 56 this.pageSize = pageSize; 57 } 58 59 60 public Integer getRowCount() { 61 return rowCount; 62 } 63 64 public void setRowCount(Integer rowCount) { 65 this.rowCount = rowCount; 66 } 67 68 69 70 71 } 72 73 74 package com.bjsxt.sxf.tag.compant; 75 76 import java.io.IOException; 77 import java.io.Writer; 78 import java.util.List; 79 import java.util.Map; 80 81 import javax.servlet.http.HttpServletRequest; 82 import javax.servlet.http.HttpServletResponse; 83 84 import org.apache.struts2.StrutsStatics; 85 import org.apache.struts2.components.Component; 86 import org.apache.struts2.dispatcher.StrutsRequestWrapper; 87 88 import com.bjsxt.sxf.util.Page; 89 import com.opensymphony.xwork2.util.ValueStack; 90 91 /** 92 * 分页标签集合类。 93 * 本示例直接从值栈中得到本次请求的分页对象,以及请求action的地址信息。所以本示例没有采用jsp页面标签属性,往后台传递信息 94 * 95 * 也可以通过标签往后台传递值。则需要建立一个所有action都会继承的pageAction,每次请求,页码当前页,总记录数,每页显示记录数,以及查询条件等等,都要在pageAction中建立 96 * 相应属性。而且所有的请求地址的参数都必须与pageAction中的属性对应。jsp页面上自定义分页标签的属性从本次请求的值栈中取出页码当前页,总记录数,每页显示记录数,然后传递给 97 * pageTag的标签类,标签类在传递给pageComponent中,然后再逻辑类中编写分页代码(本示例没用这种情况,但标签建立了相应的属性) 98 * 99 * 100 * @ClassName: PageComponent 101 * @Description: TODO(这里用一句话描述这个类的作用) 102 * @author 尚晓飞 103 * @date 2014-10-23 下午4:20:17 104 * 105 */ 106 public class PageComponent extends Component { 107 private Integer pageNo;//当前页 108 private Integer pageSize;//页面显示记录数 109 private Integer rowCount;//总记录数 110 private String reqUrl;//标签所在页面的请求地址url 111 112 113 public PageComponent(ValueStack stack,HttpServletRequest request,HttpServletResponse response) { 114 super(stack); 115 116 } 117 118 @Override 119 public boolean end(Writer writer, String body) { 120 // TODO Auto-generated method stub 121 return super.end(writer, body); 122 } 123 124 @Override 125 public boolean start(Writer writer) { 126 127 128 129 //获取值栈 130 ValueStack stack=this.getStack(); 131 Map cont= this.getStack().getContext(); 132 StrutsRequestWrapper req=(StrutsRequestWrapper)cont.get(StrutsStatics.HTTP_REQUEST); 133 //获取请求action的地址 134 //示例:/Struts2HibernateSpring/StudentAction!queryStudent 135 String url=(String)req.getAttribute("javax.servlet.forward.request_uri"); 136 //获取请求参数的地址 137 //示例:seachName=%E5%B0%9A%E6%99%93%E9%A3%9E&pageNo=1 138 //如果不存在请求参数,则返回是null 也就是说paramString是null 139 String paramString=(String) req.getAttribute("javax.servlet.forward.query_string"); 140 //从值栈中获取分页对 141 Page page=(Page) stack.findValue("page"); 142 //获取页码传递的参数 此处每页显示记录数为后台默认控制,所以不用拼接pageSize(每页显示多少条记录)的参数传递。 143 //将页码数参数,放在url的最后 144 String newUrl=""; 145 if(paramString!=null&&!paramString.equals("")){ 146 //有请求参数 147 Integer index=paramString.lastIndexOf("pageNo"); 148 paramString=paramString.substring(0,index); 149 newUrl=url+"?"+paramString; 150 151 }else{ 152 newUrl=url+"?"; 153 } 154 155 //拼接分页代码 156 StringBuffer sb=new StringBuffer(""); 157 158 /** 159 * 简单的页面分页html代码 160 * <table border="2"> 161 <tr> 162 <td>总共页数<td> 163 <td>10</td> 164 <td>当前页数</td> 165 <td>2</td> 166 <td>》》</td> 167 </tr> 168 <tr> 169 <td>首页</td> 170 <td>上一页</td> 171 <td>1,<b style="color: red;">2</b>,3,4,5</td> 172 <td>下一页</td> 173 <td>尾页</td> 174 </tr> 175 </table> 176 */ 177 sb.append("<table border=\"2\">"); 178 sb.append("<tr>"); 179 sb.append("<td>总共页数</td>"); 180 sb.append("<td>"+page.getPageCount()+"</td>"); 181 sb.append("<td>当前页数</td>"); 182 sb.append("<td>"+page.getPageNum()+"</td>"); 183 sb.append("<td>》》</td>"); 184 sb.append("</tr>"); 185 sb.append("<tr>"); 186 sb.append("<td><a href=\""+newUrl+"pageNo="+page.getFirstPage()+"\">首页</a></td>"); 187 sb.append("<td><a href=\""+newUrl+"pageNo="+page.getPreviousPage()+"\">上一页</a></td>"); 188 List<Integer> pageList=page.getPageList(); 189 if(pageList!=null&&pageList.size()>0){ 190 sb.append("<td>"); 191 //有页码列表 192 for(int i=0;i<pageList.size();i++){ 193 Integer num=pageList.get(i); 194 Integer pageNum=page.getPageNum(); 195 if(pageNum==num){ 196 sb.append("<a href=\""+newUrl+"pageNo="+num+"\"><b style=\"color: red;\">"+num+"</b></a>,"); 197 }else{ 198 sb.append("<a href=\""+newUrl+"pageNo="+num+"\">"+num+"</a>,"); 199 } 200 201 } 202 sb.append("</td>"); 203 }else{ 204 sb.append("<td>0</td>"); 205 } 206 sb.append("<td><a href=\""+newUrl+"pageNo="+page.getNextPage()+"\">下一页</a></td>"); 207 sb.append("<td><a href=\""+newUrl+"pageNo="+page.getLastPage()+"\">尾页</a></td>"); 208 sb.append("</tr>"); 209 sb.append("</table>"); 210 211 try { 212 writer.write(sb.toString()); 213 } catch (IOException e) { 214 // TODO Auto-generated catch block 215 e.printStackTrace(); 216 } 217 218 return false; 219 } 220 221 222 223 public Integer getPageNo() { 224 return pageNo; 225 } 226 227 public void setPageNo(Integer pageNo) { 228 this.pageNo = pageNo; 229 } 230 231 public Integer getPageSize() { 232 return pageSize; 233 } 234 235 public void setPageSize(Integer pageSize) { 236 this.pageSize = pageSize; 237 } 238 239 public Integer getRowCount() { 240 return rowCount; 241 } 242 243 public void setRowCount(Integer rowCount) { 244 this.rowCount = rowCount; 245 } 246 247 public String getReqUrl() { 248 return reqUrl; 249 } 250 251 public void setReqUrl(String reqUrl) { 252 this.reqUrl = reqUrl; 253 } 254 255 256 }
第三步:jsp页面测试
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%@ taglib uri="/struts-tags" prefix="s"%> 3 <%@ taglib uri="StudentTags" prefix="stu" %> 4 <% 5 String path = request.getContextPath(); 6 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 7 %> 8 9 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 10 <html> 11 <head> 12 <base href="<%=basePath%>"> 13 14 <title>My JSP 'list.jsp' starting page</title> 15 16 <meta http-equiv="pragma" content="no-cache"> 17 <meta http-equiv="cache-control" content="no-cache"> 18 <meta http-equiv="expires" content="0"> 19 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 20 <meta http-equiv="description" content="This is my page"> 21 <!-- 22 <link rel="stylesheet" type="text/css" href="styles.css"> 23 --> 24 25 </head> 26 27 <body> 28 <h1>学生表</h1> 29 <table border="2"> 30 <tr> 31 <td>id</td> 32 <td>姓名</td> 33 <td>性别</td> 34 <td>班级</td> 35 </tr> 36 <s:iterator value="#root.list" var="stu"> 37 <tr> 38 <td><s:property value="#stu.id"/></td> 39 <td><s:property value="#stu.name"/></td> 40 <td><s:property value="#stu.sex"/></td> 41 <td><s:property value="#stu.classRoom.name"/></td> 42 </tr> 43 </s:iterator> 44 </table> 45 <h1>分页列表</h1> 46 <!-- 自定义的分页标签,本示例没有用自定义标签中的属性往标签类中传递值 --> 47 <stu:page/> 48 49 </body> 50 </html>
第四步:显示效果