Struts2中实现自定义分页标签 和功能扩展

×××自定义分页标签清晰请见 http://tangshuo.iteye.com/blog/189447 ×××
×××功能扩展 http://tangshuo.iteye.com/blog/189820 ×××
Struts2中实现自定义标签很简单,主要分为3步:

1.创建taglib文件(.tld),编写标签声明。

2.编写自定义标签类。

3.在页面中使用标签。

下面以一个自定义的分页标签为例,进行说明。

其实,开发自定义标签并不需要Struts2的支持,一般情况下,只需要继承javax.servlet.jsp.tagext.BodyTagSupport类,重写doStartTag,doEndTag等方法即可。这里在实现自定义标签时,继承的2个类分别是org.apache.struts2.views.jsp.ComponentTagSupport和org.apache.struts2.components.Component,ComponentTagSupport实际上是对BodyTagSupport的一次封装,看一下ComponentTagSupport类的继承关系就明了了:

Java代码
java.lang.Object
extended by javax.servlet.jsp.tagext.TagSupport
extended by javax.servlet.jsp.tagext.BodyTagSupport
extended by org.apache.struts2.views.jsp.StrutsBodyTagSupport
extended by org.apache.struts2.views.jsp.ComponentTagSupport

继承ComponentTagSupport类是为了获得标签中的属性值,并包装成Component对象。继承Component类是为了从Struts2中的ValueStack中获得相对应的值。

1.声明自定义标签。

首先,需要创建一个tld文件,这是一个标准的XML文件,这个文件中就包含有对自定义标签的声明,声明指出了标签的名字,实现标签的类,标签的属性等信息。当在页面中使用该标签时,web服务器就会从这个文件中找出相对应的标签类,并实例化后执行。这个文件其实与struts.xml文件的作用相类似。

tangs.tld

Xml代码

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>2.2.3</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>tangs</short-name>
<uri>/tangs</uri>
<display-name>"Tangs Tags"</display-name>

<tag>
<name>pages</name>
<tag-class>com.tangs.tag.PageTag</tag-class> //标签类
<body-content>empty</body-content>
<attribute> //标签中的属性
<name>cpage</name> //属性名
<required>true</required> //是否必须
<rtexprvalue>true</rtexprvalue> //表示该自定义标签的某属性的值可以直接指定或者通过动态计算指定
</attribute>
<attribute>
<name>total</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>url</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
2.编写标签类

PageTag.java

Java代码
package com.tangs.tag;

import com.opensymphony.xwork2.util.ValueStack;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ComponentTagSupport;

/**
* 分页标签
* @author tangs
*/
public class PageTag extends ComponentTagSupport {
private String cpage; //当前页
private String total; //总页数
private String url; //请求地址

public void setCpage(String cpage) {
this.cpage = cpage;
}

public void setTotal(String total) {
this.total = total;
}

public void setUrl(String url) {
this.url = url;
}

@Override
public Component getBean(ValueStack arg0, HttpServletRequest arg1, HttpServletResponse arg2) {
return new Pages(arg0); //返回Pages Component,分页的逻辑处理都在这个Component中
}

//获得参数
protected void populateParams() {
super.populateParams();

Pages pages = (Pages)component;
pages.setCpage(cpage);
pages.setTotal(total);
pages.setUrl(url);
}
}


Pages.java

Java代码
package com.tangs.tag;

import com.opensymphony.xwork2.util.ValueStack;
import java.io.IOException;
import java.io.Writer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.struts2.components.Component;

/**
* 分页逻辑Bean
* @author tangs
*/
public class Pages extends Component {
private String cpage;
private String total;
private String url;

public String getCpage() {
return cpage;
}

public void setCpage(String cpage) {
this.cpage = cpage;
}

public String getTotal() {
return total;
}

public void setTotal(String total) {
this.total = total;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}


public Pages(ValueStack arg0) {
super(arg0);
}

@Override
public boolean start(Writer writer) {
boolean result = super.start(writer);
try {
StringBuilder str = new StringBuilder();
boolean isValid = true;

//从ValueStack中取出数值
if (isValid) {
if (total.startsWith("%{") && total.endsWith("}")) {
total = total.substring(2, total.length() -1);
total = (String)this.getStack().findValue(total);
isValid = total == null ? false : true;
} else {
isValid = false;
}
}
if (isValid) {
if (cpage.startsWith("%{") && cpage.endsWith("}")) {
cpage = cpage.substring(2, cpage.length() - 1);
cpage = (String)this.getStack().findValue(cpage);
isValid = cpage == null ? false : true;
} else {
isValid = false;
}
}
if (isValid) {
if (url.startsWith("%{") && url.endsWith("}")) {
url = url.substring(2, url.length() - 1);
url = (String)this.getStack().findValue(url);
isValid = url == null ? false : true;
} else {
isValid = false;
}
}

if (isValid) {
Integer cpageInt = Integer.valueOf(cpage);
//当前页与总页数相等
if (cpage.equals(total)) {
//如果total = 1,则无需分页,显示“[第1页] [共1页]”
if ("1".equals(total)) {
str.append("[第 " + cpage + " 页]");
str.append(" [共 " + total + " 页]");
} else {
//到达最后一页,显示“[首页] [上一页] [末页]”
str.append("<a href='");
str.append(url);
str.append("?cpage=1&total="+total+"&url="+url);
str.append("'>[首页]</a> <a href='");
str.append(url);
str.append("?cpage=" + (cpageInt - 1) + "&total=" + total+"&url="+url);
str.append("'>[上一页]</a> <a href='");
str.append(url);
str.append("?cpage=" + total + "&total=" + total+"&url="+url);
str.append("'>[末页]</a>");
}
} else {
//当前页与总页数不相同
if ("1".equals(cpage)) {
//第一页,显示“[首页] [下一页] [末页]”
str.append("<a href='");
str.append(url);
str.append("?cpage=1&total="+total+"&url="+url);
str.append("'>[首页]</a> <a href='");
str.append(url);
str.append("?cpage=" + (cpageInt + 1) + "&total=" + total+"&url="+url);
str.append("'>[下一页]</a> <a href='");
str.append(url);
str.append("?cpage=" + total + "&total=" + total+"&url="+url);
str.append("'>[末页]</a>");
} else {
//不是第一页,显示“[首页] [上一页] [下一页] [末页]”
str.append("<a href='");
str.append(url);
str.append("?cpage=1&total="+total+"&url="+url);
str.append("'>[首页]</a> <a href='");
str.append(url);
str.append("?cpage=" + (cpageInt - 1) + "&total=" + total+"&url="+url);
str.append("'>[上一页]</a> <a href='");
str.append(url);
str.append("?cpage=" + (cpageInt + 1) + "&total=" + total+"&url="+url);
str.append("'>[下一页]</a> <a href='");
str.append(url);
str.append("?cpage=" + total + "&total=" + total+"&url="+url);
str.append("'>[末页]</a>");
}
}
}

writer.write(str.toString());

} catch (IOException ex) {
Logger.getLogger(Pages.class.getName()).log(Level.SEVERE, null, ex);
}
return result;
}
}

3.服务端

服务端主要是获得请求然后转向显示的页面

DisplayAction.java

Java代码
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package com.tangs.action;

import com.opensymphony.xwork2.ActionSupport;

/**
*
* @author tangs
*/
public class DisplayAction extends ActionSupport {
private String cpage;
private String total;
private String url;

public String list() {

//Get data from server
//...
//这里没有做任何逻辑,直接跳转到了页面
return SUCCESS;
}
public String getCpage() {
return cpage;
}

public void setCpage(String cpage) {
this.cpage = cpage;
}

public String getTotal() {
return total;
}

public void setTotal(String total) {
this.total = total;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}


}

struts.xml

Xml代码

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd" >
<struts>
<package name="tagTest" extends="struts-default">
<action name="list" class="com.tangs.action.DisplayAction">
<result name="success">/list.jsp</result>
</action>
</package>
</struts>

4.在页面中使用标签

list.jsp

Html代码
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="tangs" uri="/WEB-INF/tangs.tld"%>
<%@ taglib prefix="s" uri="/WEB-INF/struts-tags.tld"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>List</title>
</head>
<body>
共 <s:property value="total"/> 页 第 <s:property value="cpage"/> 页

<tangs:pages cpage="%{cpage}" total="%{total}" url="%{url}"/>
</body>
</html>



好了,启动服务器,从浏览器中输入http://localhost:7001/TagTest/list.page?cpage=1&total=5&url=list.page

就会得到下面的结果:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值