Struts2 下 基于Freemarker模板技术的分页组件设计

来源:互联网 发布:linux libevent 安装 编辑:程序博客网 时间:2024/05/01 04:17

基于struts2的程序设计中,一定会用到struts自带的标签库,提供了一些常用的表单元素和逻辑控制标签的封装,而我们在项目中常用的分页标签却没有直接提供,通过学习struts2的源码分析我们可以看到,struts2的标签库默认是使用freemarker模板技术实现的,如图


在各个单独的模板里定义了具体的页面展现元素,因此我们可以参考官方标签的做法来定制我们的分页标签

1.编写分页组件类Pagination

这个类用于向模板中传递参数使用的

[java] view plaincopyprint?
  1. package com.crazycoder2010.demo.pagination;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.http.HttpServletResponse;  
  5.   
  6. import org.apache.struts2.components.UIBean;  
  7. import org.apache.struts2.views.annotations.StrutsTag;  
  8.   
  9. import com.opensymphony.xwork2.util.ValueStack;  
  10. @StrutsTag(  
  11.         name="pagination",  
  12.         tldTagClass="com.crazycoder2010.demo.pagination.PaginationTag",  
  13.         description="Render a pagination component",  
  14.         allowDynamicAttributes=true)  
  15. public class Pagination extends UIBean {//继承自Struts2的标签Bean  
  16.     private String pager;//分页对象  
  17.     private String formId;//查询时需要提交的表单ID  
  18.     public Pagination(ValueStack stack, HttpServletRequest request,  
  19.             HttpServletResponse response) {  
  20.         super(stack, request, response);  
  21.     }  
  22.     private static final String TEMPLATE = "pagination";  
  23.     @Override  
  24.     protected String getDefaultTemplate() {  
  25.         return TEMPLATE;  
  26.     }  
  27.     @Override  
  28.     protected void evaluateExtraParams() {//这个函数作用在与把值添加到valueStack中,这样在页面上就可以直接通过${parameters.pager.pageCount}调用  
  29.         if (pager != null) {  
  30.             addParameter("pager", findValue(pager));  
  31.         }  
  32.         if(formId != null){  
  33.             addParameter("formId", findString(formId));  
  34.         }  
  35.     }  
  36.     public String getPager() {  
  37.         return pager;  
  38.     }  
  39.     public void setPager(String pager) {  
  40.         this.pager = pager;  
  41.     }  
  42.     public String getFormId() {  
  43.         return formId;  
  44.     }  
  45.     public void setFormId(String formId) {  
  46.         this.formId = formId;  
  47.     }  
  48. }  
2.编写分页标签PaginationTag

这个就是自定义标签,用来从页面上传递参数,在基于struts的标签实现中,这个类的内部不再去负责渲染页面逻辑,而是直接通过委托将渲染交给对应的组件(Pagination)和模板(pagination.ftl)去实现

[java] view plaincopyprint?
  1. package com.crazycoder2010.demo.pagination;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.http.HttpServletResponse;  
  5.   
  6. import org.apache.struts2.components.Component;  
  7. import org.apache.struts2.views.jsp.ui.AbstractUITag;  
  8.   
  9. import com.opensymphony.xwork2.util.ValueStack;  
  10.   
  11. /** 
  12.  * @author Kevin 
  13.  * 
  14.  */  
  15. public class PaginationTag extends AbstractUITag {//这个AbstractUITag也是继承在jsp的JspTagSupport,本质上还是j2ee的东东  
  16.     private static final long serialVersionUID = -8042181780566234704L;  
  17.     private String pager;  
  18.     private String formId;  
  19.       
  20.     public String getPager() {  
  21.         return pager;  
  22.     }  
  23.   
  24.     public void setPager(String pager) {  
  25.         this.pager = pager;  
  26.     }  
  27.   
  28.     public String getFormId() {  
  29.         return formId;  
  30.     }  
  31.   
  32.     public void setFormId(String formId) {  
  33.         this.formId = formId;  
  34.     }  
  35.   
  36.     @Override  
  37.     public Component getBean(ValueStack stack, HttpServletRequest req,  
  38.             HttpServletResponse res) {  
  39.         return new Pagination(stack, req, res);  
  40.     }  
  41.     protected void populateParams() {  
  42.         super.populateParams();  
  43.   
  44.         Pagination pagination = ((Pagination) component);  
  45.         pagination.setFormId(formId);  
  46.         pagination.setPager(pager);  
  47.     }  
  48. }  
4.编写分页标签的tld文件

放在WEB-INF\tld\pagination.tld里

[html] view plaincopyprint?
  1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>  
  2. <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd">  
  3.   <display-name>"Struts2 Pagination Tags"</display-name>  
  4.   <tlib-version>1.0</tlib-version>  
  5.   <short-name>p</short-name>  
  6.   <uri>/pagination-tags</uri>  
  7.   <tag>  
  8.     <name>pagination</name>  
  9.     <tag-class>com.crazycoder2010.demo.pagination.PaginationTag</tag-class>  
  10.     <body-content>JSP</body-content>  
  11.     <attribute>  
  12.       <name>formId</name>  
  13.       <required>true</required>  
  14.       <rtexprvalue>false</rtexprvalue>  
  15.     </attribute>  
  16.     <attribute>  
  17.       <name>pager</name>  
  18.       <required>true</required>  
  19.       <rtexprvalue>false</rtexprvalue>  
  20.     </attribute>  
  21.     <dynamic-attributes>false</dynamic-attributes>  
  22.   </tag>  
  23. </taglib>  

5.编写模板pagination.ftl

这里为了演示,只是搞了一个简单的demo,简陋的很,将写好的ftl模板放在webapp\template\simple目录下,注意一下在我的程序里是设置了 struts的struts.ui.theme=simple所以才放在这个目录下的,如果未这个配置,则需要放在webapp\template\xhml文件夹下

[html] view plaincopyprint?
  1. <#list 1..parameters.pager.pageCount as p>  
  2.     <#if p==parameters.pager.currentPage>  
  3.         ${p}  
  4.     <#else><a href="#" onClick="goto(${p})"/>${p}</a>  
  5.     </#if>  
  6. </#list>  
  7. <script>  
  8.     function goto(p){  
  9.         document.getElementsByName('pager.currentPage')[0].value=p;  
  10.         document.getElementById('${parameters.formId}').submit();//点击某一页就是提交一下表单,这样分页时查询条件就会自动带到下一页  
  11.     }  
  12. </script>  
6.些个demo action,默认读取数据
[java] view plaincopyprint?
  1. package com.crazycoder2010.demo.action;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import com.crazycoder2010.demo.domain.User;  
  7. import com.crazycoder2010.demo.pagination.Pager;  
  8. import com.opensymphony.xwork2.ActionSupport;  
  9.   
  10. public class HelloWorld extends ActionSupport {  
  11.     private static final long serialVersionUID = -2074005942987876477L;  
  12.     private List<User> users = new ArrayList<User>();  
  13.     private Pager pager = new Pager();  
  14.     @Override  
  15.     public String execute() throws Exception {  
  16.         this.getPager().setTotalItems(init().size());  
  17.         this.setUsers(pagedUsers());  
  18.         return SUCCESS;  
  19.     }  
  20.       
  21.     private List<User> init(){  
  22.         List<User> users = new ArrayList<User>(102);  
  23.         for(int i = 0; i < 102; i++){  
  24.             User user = new User();  
  25.             user.setId(i+1);  
  26.             user.setName("USER_"+(i+1));  
  27.             users.add(user);  
  28.         }  
  29.         return users;  
  30.     }  
  31.       
  32.     private List<User> pagedUsers(){  
  33.         int current = this.pager.getCurrentPage();  
  34.         List<User> users = this.init();  
  35.         int from = (current-1)*pager.getPageSize();  
  36.         int to = from + pager.getPageSize();  
  37.         return users.subList(from, to);  
  38.     }  
  39.   
  40.     public List<User> getUsers() {  
  41.         return users;  
  42.     }  
  43.   
  44.     public void setUsers(List<User> users) {  
  45.         this.users = users;  
  46.     }  
  47.   
  48.     public Pager getPager() {  
  49.         return pager;  
  50.     }  
  51.   
  52.     public void setPager(Pager pager) {  
  53.         this.pager = pager;  
  54.     }  
  55. }  
7.页面引用标签

[html] view plaincopyprint?
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <%@ taglib prefix="s" uri="/struts-tags"%>   
  4. <%@ taglib prefix="p" uri="/pagination-tags"%>   
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  6. <html>  
  7. <head>  
  8. <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">  
  9. <title>Insert title here</title>  
  10. </head>  
  11. <body>  
  12. <form action="helloWorld.action" id="helloForm">  
  13.     <input name="userName"><input type="submit" value="查询"/>  
  14.     <s:hidden name="pager.currentPage"/>  
  15. </form>  
  16. <table>  
  17.     <thead>  
  18.         <tr>  
  19.             <td>id</td>  
  20.             <td>name</td>  
  21.         </tr>  
  22.     </thead>  
  23.     <tbody>  
  24.         <s:iterator value="users">  
  25.         <tr>  
  26.             <td><s:property value="id"/></td>  
  27.             <td><s:property value="name"/></td>  
  28.             </tr>  
  29.         </s:iterator>  
  30.     </tbody>  
  31. </table>  
  32. <p:pagination pager="pager" formId="helloForm"></p:pagination>  
  33. </body>  
  34. </html>  
8.运行效果

总结:

   网上看到很多到处抄来抄去的例子,很大一部分都是直接把这些分页的代码写在java代码里,if else一堆,本质上还是没有理解struts2标签的内部实现逻辑,既然用了struts2就要最大化的发挥框架的作用,采用模板技术来定制组件的展示逻辑既可以达到组件化编程的效果,又可以使代码有更好的可读性和可维护性

0 0
原创粉丝点击