您的位置:首页 > 其它

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

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



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

1.编写分页组件类Pagination

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

package com.crazycoder2010.demo.pagination;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.components.UIBean;
import org.apache.struts2.views.annotations.StrutsTag;

import com.opensymphony.xwork2.util.ValueStack;
@StrutsTag(
name="pagination",
tldTagClass="com.crazycoder2010.demo.pagination.PaginationTag",
description="Render a pagination component",
allowDynamicAttributes=true)
public class Pagination extends UIBean {//继承自Struts2的标签Bean
private String pager;//分页对象
private String formId;//查询时需要提交的表单ID
public Pagination(ValueStack stack, HttpServletRequest request,
HttpServletResponse response) {
super(stack, request, response);
}
private static final String TEMPLATE = "pagination";
@Override
protected String getDefaultTemplate() {
return TEMPLATE;
}
@Override
protected void evaluateExtraParams() {//这个函数作用在与把值添加到valueStack中,这样在页面上就可以直接通过${parameters.pager.pageCount}调用
if (pager != null) {
addParameter("pager", findValue(pager));
}
if(formId != null){
addParameter("formId", findString(formId));
}
}
public String getPager() {
return pager;
}
public void setPager(String pager) {
this.pager = pager;
}
public String getFormId() {
return formId;
}
public void setFormId(String formId) {
this.formId = formId;
}
}
2.编写分页标签PaginationTag

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

package com.crazycoder2010.demo.pagination;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ui.AbstractUITag;

import com.opensymphony.xwork2.util.ValueStack;

/**
* @author Kevin
*
*/
public class PaginationTag extends AbstractUITag {//这个AbstractUITag也是继承在jsp的JspTagSupport,本质上还是j2ee的东东
private static final long serialVersionUID = -8042181780566234704L;
private String pager;
private String formId;

public String getPager() {
return pager;
}

public void setPager(String pager) {
this.pager = pager;
}

public String getFormId() {
return formId;
}

public void setFormId(String formId) {
this.formId = formId;
}

@Override
public Component getBean(ValueStack stack, HttpServletRequest req,
HttpServletResponse res) {
return new Pagination(stack, req, res);
}
protected void populateParams() {
super.populateParams();

Pagination pagination = ((Pagination) component);
pagination.setFormId(formId);
pagination.setPager(pager);
}
}
4.编写分页标签的tld文件

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

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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"> <display-name>"Struts2 Pagination Tags"</display-name>
<tlib-version>1.0</tlib-version>
<short-name>p</short-name>
<uri>/pagination-tags</uri>
<tag>
<name>pagination</name>
<tag-class>com.crazycoder2010.demo.pagination.PaginationTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>formId</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>pager</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<dynamic-attributes>false</dynamic-attributes>
</tag>
</taglib>


5.编写模板pagination.ftl

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

<#list 1..parameters.pager.pageCount as p>
<#if p==parameters.pager.currentPage>
${p}
<#else><a href="#" onClick="goto(${p})"/>${p}</a>
</#if>
</#list>
<script>
function goto(p){
document.getElementsByName('pager.currentPage')[0].value=p;
document.getElementById('${parameters.formId}').submit();//点击某一页就是提交一下表单,这样分页时查询条件就会自动带到下一页
}
</script>
6.些个demo action,默认读取数据

package com.crazycoder2010.demo.action;

import java.util.ArrayList;
import java.util.List;

import com.crazycoder2010.demo.domain.User;
import com.crazycoder2010.demo.pagination.Pager;
import com.opensymphony.xwork2.ActionSupport;

public class HelloWorld extends ActionSupport {
private static final long serialVersionUID = -2074005942987876477L;
private List<User> users = new ArrayList<User>();
private Pager pager = new Pager();
@Override
public String execute() throws Exception {
this.getPager().setTotalItems(init().size());
this.setUsers(pagedUsers());
return SUCCESS;
}

private List<User> init(){
List<User> users = new ArrayList<User>(102);
for(int i = 0; i < 102; i++){
User user = new User();
user.setId(i+1);
user.setName("USER_"+(i+1));
users.add(user);
}
return users;
}

private List<User> pagedUsers(){
int current = this.pager.getCurrentPage();
List<User> users = this.init();
int from = (current-1)*pager.getPageSize();
int to = from + pager.getPageSize();
return users.subList(from, to);
}

public List<User> getUsers() {
return users;
}

public void setUsers(List<User> users) {
this.users = users;
}

public Pager getPager() {
return pager;
}

public void setPager(Pager pager) {
this.pager = pager;
}
}
7.页面引用标签

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="p" uri="/pagination-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action="helloWorld.action" id="helloForm">
<input name="userName"><input type="submit" value="查询"/>
<s:hidden name="pager.currentPage"/>
</form>
<table>
<thead>
<tr>
<td>id</td>
<td>name</td>
</tr>
</thead>
<tbody>
<s:iterator value="users">
<tr>
<td><s:property value="id"/></td>
<td><s:property value="name"/></td>
</tr>
</s:iterator>
</tbody>
</table>
<p:pagination pager="pager" formId="helloForm"></p:pagination>
</body>
</html>
8.运行效果



总结:

网上看到很多到处抄来抄去的例子,很大一部分都是直接把这些分页的代码写在java代码里,if else一堆,本质上还是没有理解struts2标签的内部实现逻辑,既然用了struts2就要最大化的发挥框架的作用,采用模板技术来定制组件的展示逻辑既可以达到组件化编程的效果,又可以使代码有更好的可读性和可维护性
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: