Struts2自定义分页标签的另一种不需ComponentTagSupport类的实现

February 13, 2015

继续阅读

这两天做一个Struts2的自定义标签,在网上看到多数将自定义标签实现的帖子都说需要如下3步:

  1. 创建taglib文件(.tld),编写标签声明。
  2. 编写自定义标签类。
  3. 在页面中使用标签。

我感觉挺麻烦的,不仅要定义tag,还得写java代码。于是研究了许久,机缘巧合之行,发现了另一种更简单的实现方式,只需要写一个tag文件即可!下面以分页自定义分页标签为例。

步骤如下:

1、在web-inf目录下新建一个tags目录,再新建一个pager.tag文件。
2、pager.tag的代码大致如下:
<%@ tag body-content="empty" pageEncoding="UTF-8"  isELIgnored="false"%>
<%@ attribute name="queryBean" required="true" rtexprvalue="true" type="com.test.PaginationQueryBean"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<li class="Page J_pager" page-index="${queryBean.pageIndex}">
    <c:set var="firstPageTarget" value="1"/>
    <c:set var="previousPageTarget" value="${queryBean.pageIndex-1}"/>
    <c:set var="nextPageTarget" value="${queryBean.pageIndex+1}"/>

    <c:set var="firstPageClass" value=""/>
    <c:set var="previousPageClass" value=""/>
    <c:set var="nextPageClass" value=""/>

    <c:set var="firstPageDisable" value="true"/>
    <c:set var="previousPageDisable" value="true"/>
    <c:set var="nextPageDisable" value="true"/>

    <c:if test="${queryBean.pageIndex == 1}">
    <c:set var="previousPageTarget" value="1"/>

    <c:set var="firstPageClass" value="disable"/>
    <c:set var="previousPageClass" value="disable"/>

    <c:set var="firstPageDisable" value="false"/>
    <c:set var="previousPageDisable" value="false"/>
    </c:if>
    <a href="#" class="J_pagerItem ${firstPageClass}" page-disable="${firstPageDisable}" paget-target="${firstPageTarget}">&lsaquo;&nbsp;第一页</a>
    <a href="#" class="J_pagerItem ${previousPageClass}" page-disable="${previousPageDisable}" paget-target="${previousPageTarget}">&laquo;&nbsp;上一页</a>
    <a href="#" class="J_pagerItem ${nextPageClass}" page-disable="${nextPageDisable}" paget-target="${nextPageTarget}">下一页&nbsp;&raquo;</a>
</li>

注意 文件开头定义了个attribute,这代表这个分页标签有个参数queryBean,至于attribute的详细属性配置可以到网上随便一搜一大堆,这里不多讲。那个type是我自定义的一个分页对象,用于保存当前页pageIndex等一些分页信息。 下边的html代码跟我们平常写jsp页面一样。注意代码中的${queryBean.pageIndex}是引用的传入的queryBean对象。

3、引用自定义标签

要使用自定义标签,就得在jsp页面开头引入。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="p" tagdir="/WEB-INF/tags" %>

注意最后引入自定义分页标签的时候,不要使用uri指向自定义的tag文件,而是使用tagdir指定自定义的tag所在的目录,即先前创建的/WEB-INF/tags目录。 最后在需要分页的地方,直接使用分页标签:

<p:page queryBean="${queryBean}"/>

p:是在jsp开头引用自定义标签的prefix前缀标识。而p:page则是指引用P对应的tagdir---/WEB-INF/tags目录下的名称为pagetag文件即page.tag 再传入参数queryBean${queryBean}是从action中获取的一个值。

总结起来,其实这种自定义标签的方式,跟include一个文件差不多,只是可以携带参数。

现在有了一个新需求:

标签中需要动态插入一段html代码。比如<div></div>写入了tag标签,但是div中间的内容是在调用tag标签的时候动态指定的。如何实现呢?

研究了半天,在这篇帖子中找到了解决方案。关键是在定义tag参数的时候,加入下面的代码:

<%@ attribute name="html" fragment="true" required="false"%>

这段代码的意思是定义一个代码片段(fragment),名称为html,可以在调用tag的时候传入。tag文件中在需要使用这个片段的地方加入如下代码:

<jsp:invoke fragment="html" />

完整的div.tag代码如下:

<%@ tag body-content="empty"  pageEncoding="UTF-8"  isELIgnored="false"%>
<%@ attribute name="html" fragment="true" required="false"%>

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div><jsp:invoke fragment="html" /></div>

使用代码如下:

<%@ taglib prefix="p" tagdir="/WEB-INF/tags" %>
...
<p:div>
    <jsp:attribute name="html">
    <img src="test.jpg"/>
    </jsp:attribute>
</p:div>