Struts2自定义标签4自定义分页标签

时间:2023-03-09 01:53:01
Struts2自定义标签4自定义分页标签

第一步: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自定义分页标签