数据的分页显示是Web应用中重点关注的内容之一,NETUI中提供了netui-data:dataGrid标签和一些相关的标签如:netui-data:configurePager 、netui-data: renderPager、netui-data: header、netui-data:rows等,它们组合起来使用可以完成数据分页显示功能。
用于设置分页显示的相关信息如默认每页显示的记录数目、导航内容等,主要的属性包括pagerFormat、pageSize、pageAction。
- netui-data: renderPager标签
netui-data:configurePager标签的pagerFormat属性仅仅是设置了导航区要显示的样式,并没有设置导航区显示的具体位置,我们需要通过netui-data: renderPager标签设定导航区的位置。
- netui-data: header标签
用于显示表格的头信息。
- netui-data:headerCell
用于显示表格头的列,如果表格需要排序,排序的参数也通过netui-data:headerCell标签对应的属性提供。支持的主要属性包括value、sortExpression、sortAction。
- value
表格中要显示的内容。
- sortExpression
排序的表达式。netui-data:dataGrid标签支持嵌入式排序功能,不过他并没有提供默认的排序实现,只是提供了相关的属性和接口。sortExpression属性中可以设置排序时使用的表达式,开发者可以通过接口获得这个表达式,然后自己将内容排序后返回给netui-data:dataGrid标签显示。
- sortAction
用于设置生成排序链接的目标地址。默认情况下生成的排序链接目标地址是当前JSP页面,但是通常情况下页面流的目标都是Action,我们可以通过设置sortAction属性将排序链接的目标地址转向Action。
- netui-data:rows标签
用于遍历数据的每一条记录。我们可以在netui-data:rows标签下面嵌套netui-data:anchorCell、netui-data:imageAnchorCell、netui-data:imageCell、netui-data:spanCell、netui-data:templateCell标签显示表格的列。
- netui-data:anchorCell
该标签用于显示超链接内容的列。主要属性包括value、action、href。Value属性用于指定超链接的显示内容,action属性指定该超链接目标action的名称,如果超链接指向JSP内容,我们需要使用href属性指定超链接的目标。
- netui-data:imageAnchorCell
该标签用于显示带超链接的图片。主要属性包括src、action、href。src属性用于指定显示图片的位置,action属性指定该超链接目标action的名称,如果超链接指向JSP内容,我们需要使用href属性指定超链接的目标。
- netui-data:imageCell
该标签用于显示简单的图片。主要的属性包括src,用于提供显示图片的位置。
- netui-data:spanCell
该标签用于显示简单的文字列。主要属性是value,用于指定该列的显示内容。
- netui-data:templateCell
该标签用于需要显示复杂内容的列。在netui-data:templateCell中可以显示任意的HTML内容、NETUI标签或者其他任意内容。
我们来看一个简单的例子,以前面显示的10个UserBean对象为例,如果我们每页显示5个对象信息,使用netui-data:dataGrid显示这些数据的代码如下。
- <netui-data:dataGrid dataSource=“pageInput.users” name=“user”>
- <netui-data:configurePager disableDefaultPager=“true”
- pagerFormat=“firstPrevNextLast” pageSize=“5”/>
- <netui-data:header>
- <netui-data:headerCell value=”用户名”/>
- <netui-data:headerCell value=”密码”/>
- </netui-data:header>
- <netui-data:rows>
- <netui-data:spanCell value=“${container.item.name}”/>
- <netui-data:spanCell value=“${container.item.password}”/>
- </netui-data:rows>
- <netui-data:footer>
- <td colspan=“2”><netui-data:renderPager/></td>
- </netui-data:footer>
- </netui-data:dataGrid>
netui-data:dataGrid标签的更多属性的应用请参考清单1,清单3 给出了格式化netui-data:dataGrid标签的css文件的内容。
需要指出的是,使用netui-data:dataGrid标签分页显示数据仅针对数据量不大的情况,因为netui-data:dataGrid标签中要显示的数据使用Java对象保存,对于大数据量的情况,由于过大的Java对象在多用户访问时很容易引起系统性能问题,严重的话会引起OutOfMemoryError,导致系统无法正常运行,这种情况下,不推荐直接使用netui-data:dataGrid标签完成分页。而是应该由开发者实现数据的逐页提取,借助于netui-data:dataGrid标签来显示当前页的数据,这样才能保证系统平稳运行。
我们不能在大数据量的情况下完全使用netui-data:dataGrid标签实现数据分页显示,而应该由开发者完成分页逻辑,仅仅借助于netui-data:dataGrid标签显示数据。
将%NETUI_HOME%目录下的Web应用编译、发布到Tomcat后(上下文路径netui),可以使用http://localhost:8080/netui/dataGridExamples.do访问这个netui:dataGrid标签的例子。
和分页显示数据相关的JSP文件的完整内容请参考清单1。
清单1 web\dataGridExample.jsp
- <%@ page language="java" contentType="text/html;charset=gb2312"%>
- <%@ page import="org.vivianj.beehive.examples.beans.UserBean" %>
- <%@ taglib uri="http://beehive.apache.org/netui/tags-databinding-1.0"
- prefix="netui-data"%>
- <%@ taglib uri="http://beehive.apache.org/netui/tags-html-1.0"
- prefix="netui"%>
- <%@ taglib uri="http://beehive.apache.org/netui/tags-template-1.0"
- prefix="netui-template"%>
- <netui:html>
- <head>
- <title>dataGrid Examples</title>
- <netui:base/>
- <link rel="stylesheet" href="css/vivianj-datagrid.css" type="text/css" />
- </head>
- <netui:body>
- <center>使用标签分页显示数据的例子</center><BR>
- <netui-data:declarePageInput name="userbeans"
- type="java.util.ArrayList" required="true" />
- <TABLE border="1" align="Center">
- <TR>
- <TD>简单分页的例子</TD>
- <TD>简单分页的例子--在表格中显示复杂内容</TD>
- </TR>
- <TR>
- <TD>
- <netui-data:dataGrid dataSource="pageInput.userbeans"
- name="user">
- <netui-data:configurePager disableDefaultPager="true"
- pagerFormat="firstPrevNextLast" pageSize="5"
- pageAction="dataGridExamples"/>
- <netui-data:header>
- <netui-data:headerCell value="用户名"/>
- <netui-data:headerCell value="密码"/>
- </netui-data:header>
- <netui-data:rows>
- <netui-data:spanCell value="${container.item.id}"/>
- <netui-data:spanCell value="${container.item.name}"/>
- </netui-data:rows>
- <netui-data:footer>
- <td colspan="2"><netui-data:renderPager/></td>
- </netui-data:footer>
- </netui-data:dataGrid>
- </TD>
- <TD>
- <netui-data:dataGrid dataSource="pageInput.userbeans"
- name="user">
- <netui-data:configurePager disableDefaultPager="true"
- pagerFormat="firstPrevNextLast" pageSize="5"
- pageAction="dataGridExamples"/>
- <netui-data:header>
- <netui-data:headerCell value="用户名"/>
- <netui-data:headerCell value="密码"/>
- </netui-data:header>
- <netui-data:rows>
- <netui-data:spanCell value="${container.item.id}"/>
- <netui-data:spanCell value="${container.item.name}"/>
- </netui-data:rows>
- <netui-data:footer>
- <td colspan="2"><netui-data:renderPager/></td>
- </netui-data:footer>
- </netui-data:dataGrid>
- </TD>
- </TR>
- <TR>
- <TD>简单分页的例子--应用CSS格式化显示</TD>
- <TD> </TD>
- </TR>
- <TR>
- <TD>
- <netui-data:dataGrid dataSource="pageInput.userbeans"
- name="user" styleClassPrefix="vivianj">
- <netui-data:configurePager disableDefaultPager="true"
- pagerFormat="firstPrevNextLast" pageSize="5"
- pageAction="dataGridExamples"/>
- <netui-data:header>
- <netui-data:headerCell value="用户名"/>
- <netui-data:headerCell value="密码"/>
- </netui-data:header>
- <netui-data:rows>
- <netui-data:spanCell value="${container.item.id}"/>
- <netui-data:spanCell value="${container.item.name}"/>
- </netui-data:rows>
- <netui-data:footer>
- <td colspan="2"><netui-data:renderPager/></td>
- </netui-data:footer>
- </netui-data:dataGrid>
- </TD>
- <TD>
-
- </TD>
- </TR>
- </TABLE>
- </netui:body>
- </netui:html>
清单2 web\Controller.java
- import javax.servlet.http.HttpSession;
- import org.apache.beehive.netui.pageflow.Forward;
- import org.apache.beehive.netui.pageflow.PageFlowController;
- import org.apache.beehive.netui.pageflow.annotations.Jpf;
- import org.vivianj.beehive.examples.beans.UserBean;
- import java.util.List;
- import java.util.ArrayList;
- import org.apache.beehive.netui.databinding.datagrid.api.DataGridState;
- import org.apache.beehive.netui.databinding.datagrid.api.DataGridStateFactory;
- import org.apache.beehive.netui.databinding.datagrid.api.sort.Sort;
- import org.apache.beehive.netui.databinding.datagrid.api.sort.SortDirection;
- import java.lang.reflect.Method;
- import java.lang.reflect.InvocationTargetException;
- import java.beans.Introspector;
- import java.beans.BeanInfo;
- import java.beans.PropertyDescriptor;
- import java.beans.IntrospectionException;
- import java.util.Comparator;
- import java.util.Collections;
- @Jpf.Controller(
- simpleActions={
- @Jpf.SimpleAction(name="begin", path="index.jsp")
- },
- sharedFlowRefs={
- @Jpf.SharedFlowRef(name="shared",
- type=shared.SharedFlow.class)
- }
- )
- public class Controller
- extends PageFlowController
- {
- @Jpf.Action(forwards = {
- @Jpf.Forward(name = "success", path = "pageInputExample.jsp") })
- public Forward pageInputExamples() {
- Forward f = new Forward("success");
- /* 向JSP页面传递数据 */
- f.addActionOutput("hellostring", "Hello World!");
- String[] strings = new String[]{"Hello World!","Hello Beehive!"};
- /* 向JSP页面传递数组 */
- f.addActionOutput("strings", strings);
- /* 向JSP页面传递自定义对象 */
- UserBean userBean = new UserBean();
- userBean.setId(100);
- userBean.setName("UserBean100");
- f.addActionOutput("userbean", userBean);
- /* 向JSP页面传递List对象 */
- List list = new ArrayList();
- list.add(userBean);
- UserBean userBean1 = new UserBean();
- userBean.setId(101);
- userBean.setName("UserBean101");
- list.add(userBean1);
-
- f.addActionOutput("userbeans", list);
- return f;
- }
- @Jpf.Action(forwards = {
- @Jpf.Forward(name = "success", path = "cellRepeaterExample.jsp") })
- public Forward cellRepeaterExamples() {
- Forward f = new Forward("success");
- ArrayList list = new ArrayList();
- for( int i = 0;i<10;i++){
- UserBean user = new UserBean();
- user.setId(i);
- user.setName("name" + i);
-
- list.add(user);
- }
-
- f.addActionOutput("userbeans", list);
- return f;
- }
- @Jpf.Action(forwards = {
- @Jpf.Forward(name = "success", path = "repeaterExample.jsp") })
- public Forward repeaterExamples() {
- Forward f = new Forward("success");
- ArrayList list = new ArrayList();
- for( int i = 0;i<10;i++){
- UserBean user = new UserBean();
- user.setId(i);
- user.setName("name" + i);
-
- list.add(user);
- }
-
- f.addActionOutput("userbeans", list);
- return f;
- }
- @Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "dataGridExample.jsp") })
- public Forward dataGridExamples() {
- Forward f = new Forward("success");
- List list = new ArrayList();
- for( int i = 0;i<10;i++){
- UserBean user = new UserBean();
- user.setId(i);
- user.setName("name" + i);
-
- list.add(user);
- }
- DataGridState dataGridState = DataGridStateFactory.getInstance(getRequest()).getDataGridState("user");
- final List<Sort> sorts = (List<Sort>)dataGridState.getSortModel().getSorts();
- if(sorts != null && sorts.size() < 2) {
- Sort sort = (Sort)sorts.get(0);
-
- SortByPropertyComparator sorter = new SortByPropertyComparator(sort);
- Collections.sort(list, sorter);
- }
-
- f.addActionOutput("userbeans", list);
- return f;
- }
- protected void onCreate()
- {
- }
- protected void onDestroy(HttpSession session)
- {
- }
- private class SortByPropertyComparator
- implements Comparator {
- private Sort _sort = null;
- SortByPropertyComparator(Sort sort) {
- _sort = sort;
- }
- public int compare(Object o1, Object o2) {
- int comparison = 0;
- Object value1 =
- extractPropertyValue(o1, _sort.getSortExpression());
- Object value2 =
- extractPropertyValue(o2, _sort.getSortExpression());
- assert value1 instanceof Comparable;
- comparison = ((Comparable) value1).compareTo(value2);
- if (_sort.getDirection() == SortDirection.ASCENDING)
- return comparison;
- else if (_sort.getDirection() ==
- SortDirection.DESCENDING)
- return -1 * comparison;
- else return 0;
- }
- private Object extractPropertyValue(
- Object object, String propertyName) {
- assert object != null;
- assert propertyName != null && !propertyName.equals("");
- Method propAccessor =
- lookupPropertyAccessor(object.getClass(), propertyName);
- if (propAccessor == null)
- throw new IllegalStateException("Unable to find” +
- “property accessor matching property name \""
- + propertyName + "\"");
- Object value = null;
- try {
- value = propAccessor.invoke(object, (Object[])null);
- }
- catch (IllegalAccessException e) {
- throw new IllegalStateException("Exception occurred “
- + ”invoking property getter \""
- + propAccessor.getName() + "\"");
- }
- catch (InvocationTargetException e) {
- throw new IllegalStateException("Exception occurred “
- + ”invoking property getter \""
- + propAccessor.getName() + "\"");
- }
- return value;
- }
- private Method lookupPropertyAccessor(
- Class clazz, String propertyName) {
- BeanInfo beanInfo = null;
- try {
- beanInfo = Introspector.getBeanInfo(clazz);
- }
- catch (IntrospectionException e) {
- throw new IllegalStateException("Unable to find “
- + ”property named \"" + propertyName + "\" on type \""
- + clazz.getName() + "\"", e);
- }
- for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors())
- {
- if (pd.getName().equalsIgnoreCase(propertyName))
- return pd.getReadMethod();
- }
- return null;
- }
- }
- }
清单3 web\css\dataGrid.css
- .vivianj{
- font: 12px;
- }
- .vivianj-header {
- color: #FFFFFF;
- background-color: #585858;
- }
- .vivianj-footer {
- color: #0000FF;
- background-color: #FFFFFF;
- }
- .vivianj-even {
- background-color: #E1E1E1;
- }
- .vivianj-odd {
- background-color: #C0C0C0;
- }
数据分页显示中的中文问题
使用netui-data:dataGrid标签显示数据时,默认生成导航超链接和其他提示信息都是英文内容,我们需要为它们提供对应的中文内容。NETUI中使用基于资源文件和Local机制的国际化处理策略,我们只需要提供对应的资源文件即可。
netui-data:dataGrid标签使用的资源文件位于org\apache\beehive\netui\databinding\datagrid\runtime\util\ data-grid-default.properties文件中,我们需要在WEB-INF\classes目录下创建org\apache\beehive\netui\databinding\datagrid\runtime\util\目录,然后在该目录下建立data-grid-default_zh_CN.properties文件,在该文件中提供对应的中文信息即可。下面是提供中文内容的data-grid-default_zh_CN.properties文件的例子。
清单4 src\org\apache\beehive\netui\databinding\datagrid\runtime\util\
data-grid-default_zh_CN.properties
- datagrid.resource.path=resources/beehive/version1/images
- datagrid.msg.nodata=\u6ca1\u6709\u5408\u9002\u7684\u5185\ u5bb9\ u7528\ u4e8e\ u663e\ u793a
- sort.asc.img=/sortdown.gif
- sort.desc.img=/sortup.gif
- sort.none.img=/sortable.gif
- pager.msg.first=\ u7b2c\ u4e00\ u9875
- pager.msg.previous=\ u4e0a\ u4e00\ u9875
- pager.msg.next=\ u4e0b\ u4e00\ u9875
- pager.msg.last=\ u6700\ u540e\ u4e00\ u9875
- pager.fmt.banner=\ u7b2c{0}\ u9875 \ u5171{1}\ u9875
- filter.sql.none= \ u6ca1\ u6709\ u8fc7\ u6ee4\ u5668
- filter.sql.equal= \ u7b49\ u4e8e
- filter.sql.notequal= \ u4e0d\ u7b49\ u4e8e
- filter.sql.greaterthan= \ u5927\ u4e8e
- filter.sql.lessthan= \ u5c0f\ u4e8e
- filter.sql.greaterthanorequal= \ u5927\ u4e8e\ u7b49\ u4e8e
- filter.sql.lessthanorequal= \ u5c0f\ u4e8e\ u7b49\ u4e8e
- filter.sql.isoneof= \ u5c5e\ u4e8e
- filter.sql.startswith= \ u4ee5\ u5b57\ u7b26\ u5f00\ u59cb
- filter.sql.contains= \ u5305\ u542b
- filter.sql.isempty= \ u7a7a\ u503c
- filter.sql.isnotempty= \ u975e\ u7a7a\ u503c
资源文件中的中文内容必须以UNICODE编码格式提供,否则无法显示,如何实现中文内容到UNICODE编码的转化请参考《应用页面流开发Web应用》章节中关于国际化部分的内容。
|