一、相关知识 1、开发自定义标签并不需要Struts2的支持,一般情况下,只需要继承javax.servlet.jsp.tagext.BodyTagSupport类,重写doStartTag,doEndTag等方法即可。 在struts2.x中实现自定义标签时,继承的2个类分别是org.apache.struts2.views.jsp.ComponentTagSupport和org.apache.struts2.components.Component.ComponentTagSupport。 ComponentTagSupport: 实际上是对BodyTagSupport的一次封装,继承ComponentTagSupport类是为了获得JSP页面中用户自定义的标签中设置的属性值,并包装成Component对象。 Component: 继承Component类是为了从Struts2中的ValueStack中获得相对应的值。 2、实现方式 2.1、tag类(继承ComponentTagSupport) 须声明的属性: 需要定义你JSP页面传来的标签设置的属性。如maxlength,并相应的set get。 须重写的方法是: public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res); 此方法就是获得一个基本类的对象。在基本类里面需要有传入ValueStack的构造函数,如果基本类逻辑里面需要request或者response,那么需要有传入ValueStack stack, HttpServletRequest req, HttpServletResponse res的构造函数; protected void populateParams() 此方法是用来将JSP页面传来的属性值赋给基本类。这里是继承来的,所以首先调用super的相应方法。我理解上面第一个方法返回的对象就是全局的一个Component对象,也就是第二个方法里面使用的对象。 第一步,生成基本类,且将ValueStack值,还有其它可选值赋给它。 第二步,JSP页面传来的属性值,通过ComponentTagSupport,利用其getter,setter来获取.将JSP页面传来的属性值,赋给基本类实例。 2.2、基本类(继承Component) 须声明的属性: 与tag类一样。 需重写的方法: 构造函数:直接调用super() public boolean start(Writer writer) 生成标签对应的html代码,并用writer输出。 二、示例 1、tld文件 <?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>page</short-name> <uri>/page</uri> <display-name>"Page Link Tags"</display-name> <tag> <name>link</name> <tag-class>com.teksun.tag.pagelink.PageLinkTag</tag-class> <body-content>empty</body-content> <attribute> <name>rowsCount</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>pageCount</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>currentPage</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib> 2、PageLinkTag public class PageLinkTag extends ComponentTagSupport { private static final long serialVersionUID = 1L; // 总行数 private String rowsCount = ""; // 总页数 private String pageCount = ""; // 当前页 private String currentPage = ""; public String getRowsCount() { return rowsCount; } public void setRowsCount(String rowsCount) { this.rowsCount = rowsCount; } public String getPageCount() { return pageCount; } public void setPageCount(String pageCount) { this.pageCount = pageCount; } public String getCurrentPage() { return currentPage; } public void setCurrentPage(String currentPage) { this.currentPage = currentPage; } @Override public Component getBean(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { return new PageLinkComp(stack); } protected void populateParams() { super.populateParams(); PageLinkComp pageLinkComp = (PageLinkComp) component; PageLink pl = new PageLink(); pl.setRowsCount(Integer.parseInt(this.getRowsCount())); pl.setPageCount(Integer.parseInt(this.getPageCount())); pl.setCurrentPage(Integer.parseInt(this.getCurrentPage())); pageLinkComp.setPl(pl); } } 3、PageLinkComp public class PageLinkComp extends Component { private PageLink pl = new PageLink(); public PageLink getPl() { return pl; } public void setPl(PageLink pl) { this.pl = pl; } public PageLinkComp(ValueStack stack) { super(stack); } @Override public boolean start(Writer writer) { // System.out.println(writer.getClass()); boolean result = super.start(writer); try { String returnValue = ""; boolean isValid = true; isValid = this.pl != null ? true : false; if (isValid) { returnValue = getPageLink(this.pl); } writer.write(returnValue); } catch (IOException e) { Logger.getLogger(PageLinkComp.class.getName()).log(Level.SEVERE, null, e); } return result; } // 获取分页链接的html代码 private String getPageLink(PageLink pl) { StringBuffer returnValue = new StringBuffer(); returnValue.append("<span>"); // 总件数>0时,才展示分页链接 if (pl.getRowsCount() > 0) { //最多展示10页的连接 //计算展示那几页的链接 int start = 1; int end = pl.getPageCount(); if (pl.getPageCount() > 10) { if ((pl.getCurrentPage() - start) > 4) { start = pl.getCurrentPage() - 4; } if ((end - pl.getCurrentPage()) > 5) { end = pl.getCurrentPage() + 5; } if (start == 1) { end = 10; } if (end == pl.getPageCount()) { start = pl.getPageCount() - 9; } } //首页&上一页 if (start > 1) { returnValue.append("<a href=\"javascript:jumpPage(1);\">1 ...</a>"); returnValue.append("<a href=\"javascript:jumpPage("); returnValue.append(pl.getCurrentPage() - 1); returnValue.append(");\">‹‹</a>"); } else { if (pl.getCurrentPage() != 1) { returnValue.append("<a href=\"javascript:jumpPage("); returnValue.append(pl.getCurrentPage() - 1); returnValue.append(");\">‹‹</a>"); } } int linkNum = start; while (linkNum <= end) { if (linkNum == pl.getCurrentPage()) { returnValue.append("<strong>"); returnValue.append(linkNum); returnValue.append("</strong>"); } else { returnValue.append("<a href=\"javascript:jumpPage("); returnValue.append(linkNum); returnValue.append(");\">"); returnValue.append(linkNum); returnValue.append("</a>"); } linkNum++; } //下一页&尾页 if (end < pl.getPageCount()) { returnValue.append("<a href=\"javascript:jumpPage("); returnValue.append(pl.getCurrentPage() + 1); returnValue.append(");\">››</a>"); returnValue.append("<a href=\"javascript:jumpPage("); returnValue.append(pl.getPageCount()); returnValue.append(");\">... "); returnValue.append(pl.getPageCount()); returnValue.append("</a>"); } else { if (pl.getCurrentPage() != pl.getPageCount()) { returnValue.append("<a href=\"javascript:jumpPage("); returnValue.append(pl.getCurrentPage() + 1); returnValue.append(");\">››</a>"); } } returnValue.append("</span>"); } return returnValue.toString(); } } 4、PageLink --一个bean public class PageLink { // 总行数 private int rowsCount = 0; // 总页数 private int pageCount = 0; // 当前页 private int currentPage = 1; public PageLink(){ } public int getRowsCount() { return rowsCount; } public void setRowsCount(int rowsCount) { this.rowsCount = rowsCount; } public int getPageCount() { return pageCount; } public void setPageCount(int pageCount) { this.pageCount = pageCount; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } } 5、使用方法 <%@ taglib uri="/page" prefix="page"%> <script type="text/javascript"> function jumpPage(pageNo) { viewForm.action = ''; viewForm.submit(); } </script> <page:link rowsCount="1001" pageCount="101" currentPage="10" /> |