做过Java Web项目的开发工程师都知道,如果单纯的使用jsp脚本开发,糅合内容和行为逻辑与一体是一个非常不好的体验,更不易于维护。所以采用了JSTL标签库,用于分离数据显示和业务逻辑,简易开发,带来优雅编程体验。JSTL 即:JSP Standard Tag Library
,一个JSP标签集合,它封装了JSP应用的通用核心功能。他依赖于standard.jar和jstl.jar两个jar包。
JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。尽量只是用核心标签,包括<c:if>、<c:choose>、<c:when>、<c:otherwise>、<c:forEach>
等,主要用于构造循环和分支结构以控制显示逻辑。标签引用:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
格式化标签一般用于日期相关的数据处理。函数标签一般用于字符串相关的数据处理。当然,这次要记录的是如何自定义标签,增强自己的数据处理需要。这里以自定义分页标签为例。
文章目录
1、实现Tag接口或者继承缺省适配的Tag相关类。
开发中通常不直接实现这些接口而是继承TagSupport/BodyTagSupport/SimpleTagSupport
类,重写doStartTag()、doEndTag()
等方法,定义标签要完成的功能。
现在已自定义分页标签为例,继承BodyTagSupport类,重写doStartTag方法。定义了一些属性。
- PageData pageData; // 分页类
- String funcName; // js 回调函数名
- String formId; // 表单的ID名
- String formUrl; // 表单提交的URL
重写doStartTag方法:
- @Override
- public int doStartTag() throws JspException {
- JspWriter out = this.pageContext.getOut();
- try {
- if (pageData == null) {
- return Tag.SKIP_BODY;
- }
- out.println(getPageHtml());
- } catch (IOException e) {
- throw new JspException(e);
- }
- return Tag.EVAL_BODY_INCLUDE;
- }
在getPageHtml方法里根据逻辑拼接html分页列表,如一个简单的例子:
- private String getPageHtml() {
- if (pageData == null) {
- return “”;
- }
- StringBuilder sBuilder = new StringBuilder();
- if (pageData.hasNext()) {
- sBuilder.append(“<li><a href=\”javascript:void(0)\” onclick=\””).append(this.funcName)
- .append(“(“).append(pageData.getPageNo()+1).append(“,”).append(pageData.getPageSize()).append(“,'”).append(formId).append(“‘,'”).append((formUrl == null || “”.equals(formUrl)?“”:formUrl))
- .append(“‘);\”>下一页</a></li>”);
- } else {
- sBuilder.append(“<li class=\”disabled\”>下一页</li>”);
- }
- if (pageData.hasPrevious()) {
- sBuilder.append(“<li><a href=\”javascript:void(0)\” onclick=\””).append(this.funcName)
- .append(“(“).append(pageData.getPageNo()-1).append(“,”).append(pageData.getPageSize()).append(“,'”).append(formId).append(“‘,'”).append((formUrl == null || “”.equals(formUrl)?“”:formUrl))
- .append(“‘);\”>上一页</a></li>”);
- } else {
- sBuilder.append(“<li class=\”disabled\”>上一页</li>”);
- }
- return sBuilder.toString();
- }
2、编写扩展名为tld的标签描述文件对自定义标签进行定义。
pages.tld
自定义标签描述了标签名,标签处理类、和相关属性定义描述:
- <tag>
- <name>page</name>
- <tag-class>com.common.test.PageTag</tag-class>
- <description>分页标签–power by wenqy.com</description>
- <attribute>
- <name>pageData</name>
- <required>true</required>
- <rtexprvalue>true</rtexprvalue>
- <description>封装分页数据类</description>
- </attribute>
- <attribute>
- <name>funcName</name>
- <required>false</required>
- <rtexprvalue>true</rtexprvalue>
- <description>选择页签触发的js函数名</description>
- </attribute>
- <attribute>
- <name>formId</name>
- <required>true</required>
- <rtexprvalue>true</rtexprvalue>
- <description>选择页签后要提交表单的ID</description>
- </attribute>
- <attribute>
- <name>formUrl</name>
- <required>false</required>
- <rtexprvalue>true</rtexprvalue>
- <description>选择页签后要跳转的页面URL</description>
- </attribute>
- </tag>
3、在JSP页面中使用taglib指令引用该标签库
Jsp头部引用tld标签描述文件。
<%@ taglib prefix="fns" uri="/WEB-INF/tlds/pages.tld" %>
调用自定义标签,formUrl属性非必须。
<fns:page pageData="${requestScope.pageData }" funcName="page" formId="myForm" />
4、js方法
表单里定义pageNo、pageSize两个隐藏域,并重写页签调用方法,使用jquery方法。
- <script type=“text/javascript”>
- // 参数: 页数、页大小、form ID、submit URL
- function page(no, size,form,url) {
- var re = /^[0-9]*$/;
- if(!re.test(size)){
- alert(‘页大小为数字’);
- return;
- }
- if(!re.test(no)){
- alert(‘页数为数字’);
- return;
- }
- if (no) {
- $(“#pageNo”).val(no);
- }
- if (size) {
- $(“#pageSize”).val(size);
- }
- if (url) {
- $(“#” + form).attr(“action”,url);
- }
- $(“#” + form).submit();
- return false;
- }
- </script>
5、pageData分页类
- /**
- *
- * @author wenqy
- *
- */
- public class PageData implements Serializable {
- private static final long serialVersionUID = 8040968899344110256L;
- protected static final int DEFAULT_PAGE_NO = 0;
- protected static final int DEFAULT_PAGE_SISE = 0;
- protected static final int DEFAULT_INDEX_BEGIN = 0;
- protected static final int DEFAULT_INDEX_END = 0;
- protected List<?> items; // 页数据
- protected Object[][] results;
- protected int pageNo; // 当前页
- protected int pageSize; // 页大小
- protected int pageCount; // 页数
- protected int totalCount;
- protected int handleCount;
- protected int lastPageSize;
- protected int columnCount;
- protected int beginIndex;
- protected int endIndex;
- protected int[] indexes; // 记录每页的起始下标
- protected String orderField; // 排序字段
- protected boolean isOrderAsc; // 升降排序
- protected String resInfo;
- protected String pageCode;
- public boolean hasNext() {
- return (this.pageNo < this.pageCount);
- }
- public boolean hasPrevious() {
- return (this.pageNo > 0);
- }
- public static int convertFromPageToStartIndex(int paramInt1, int paramInt2) {
- return ((paramInt1 – 1) * paramInt2);
- }
- public int currentPageNo() {
- return getPageNo();
- }
- public int getNextIndex() {
- int i = getBeginIndex() + this.pageSize;
- if (i >= this.totalCount)
- return getBeginIndex();
- return i;
- }
- public int getPreviousIndex() {
- int i = getBeginIndex() – this.pageSize;
- if (i < 0)
- return 0;
- return i;
- }
- public List<?> getItems() {
- return this.items;
- }
- public void setItems(List<?> paramList) {
- this.items = paramList;
- }
- public int getPageNo() {
- return this.pageNo;
- }
- public void setPageNo(int paramInt) {
- this.pageNo = paramInt;
- }
- public int getPageSize() {
- return this.pageSize;
- }
- public void setPageSize(int paramInt) {
- this.pageSize = paramInt;
- }
- public int getPageCount() {
- if (this.totalCount < 0)
- return –1;
- if (this.totalCount == 0)
- return 0;
- if (this.pageSize > 0) {
- int i = this.totalCount / this.pageSize;
- if (this.totalCount % this.pageSize > 0)
- ;
- this.pageCount = (++i);
- } else {
- this.pageCount = 1;
- this.pageSize = this.totalCount;
- }
- return this.pageCount;
- }
- public void setPageCount(int paramInt) {
- this.pageCount = paramInt;
- }
- public int getTotalCount() {
- return this.totalCount;
- }
- public void setTotalCount(int paramInt) {
- if (paramInt > 0) {
- this.totalCount = paramInt;
- if (this.pageSize <= 0)
- return;
- int i = this.totalCount / this.pageSize;
- if (paramInt % this.pageSize > 0)
- ;
- this.indexes = new int[++i];
- for (int j = 0; j < i; ++j)
- this.indexes[j] = (this.pageSize * j);
- } else {
- this.totalCount = 0;
- }
- }
- public int getBeginIndex() {
- return this.beginIndex;
- }
- public void setBeginIndex(int paramInt) {
- if (this.totalCount <= 0)
- this.beginIndex = 0;
- else if (paramInt >= this.totalCount)
- this.beginIndex = this.indexes[(this.indexes.length – 1)];
- else if (paramInt < 0)
- this.beginIndex = 0;
- else if (this.pageSize > 0)
- this.beginIndex = this.indexes[(paramInt / this.pageSize)];
- else
- this.beginIndex = paramInt;
- }
- public int getEndIndex() {
- return this.endIndex;
- }
- public void setEndIndex(int paramInt) {
- this.endIndex = paramInt;
- }
- public int getLastPageSize() {
- if (this.totalCount < 0)
- return –1;
- if (this.totalCount == 0)
- return 0;
- int i = this.totalCount % this.pageSize;
- if (i > 0)
- return i;
- return this.pageSize;
- }
- public void setLastPageSize(int paramInt) {
- this.lastPageSize = paramInt;
- }
- public int getColumnCount() {
- return this.columnCount;
- }
- public void setColumnCount(int paramInt) {
- this.columnCount = paramInt;
- }
- public int getHandleCount() {
- return this.handleCount;
- }
- public void setHandleCount(int paramInt) {
- this.handleCount = paramInt;
- }
- public int[] getIndexes() {
- return this.indexes;
- }
- public void setIndexes(int[] paramArrayOfInt) {
- this.indexes = paramArrayOfInt;
- }
- public String getOrderField() {
- return this.orderField;
- }
- public void setOrderField(String paramString) {
- this.orderField = paramString;
- }
- public boolean isOrderAsc() {
- return this.isOrderAsc;
- }
- public void setOrderAsc(boolean paramBoolean) {
- this.isOrderAsc = paramBoolean;
- }
- public Object[][] getResults() {
- return this.results;
- }
- public void setResults(Object[][] paramArrayOfObject) {
- this.results = paramArrayOfObject;
- }
- public String getResInfo() {
- return this.resInfo;
- }
- public void setResInfo(String paramString) {
- this.resInfo = paramString;
- }
- }
封装Dao层的分页方法,传入pageData。Jsp会被Java容器,如:Tomcat翻译成Servlet,获取pageContext对象,调用doStartTag方法。
使用标签库可以对内容显示和业务逻辑的解耦有很大帮助,如果觉得现有标签库不能满足需要还可以自定义标签。当然也是可以选择其他模板引擎,如freemarker、velocity等等。
参考:
http://tomcat.apache.org/taglibs/standard/ Standard Taglib
发表评论