- 浏览: 212910 次
- 性别:
- 来自: 哈尔滨
文章分类
最新评论
-
lizhenzhendebishe:
提示An error was discovered proce ...
WebService:Axis客户端调用需要身份验证的CXF服务 -
yuanliangding:
学习了。不太接触底层的东西
UNIX系统的IO模型 -
_copythat:
加油,。。。
阳光总会在风雨之后洒向苍茫 -
donlianli:
莫非去淘宝菜鸟网络了?
阳光总会在风雨之后洒向苍茫 -
菜鸟小于:
我也是哈尔滨的,在广州做了三年的开发,可是实际上我们是在维护一 ...
阳光总会在风雨之后洒向苍茫
LDAP服务器端可以支持分页查询,但是有个前提条件,需要客户端先发送按关键字排序的指令后,才能执行分页查询。排序的过程是比较耗费时间的,需要对服务器做很多优化的操作。
我的方法是在迭代结果集的时候实现分页,见代码:
package ldap.page; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.DirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.naming.ldap.InitialLdapContext; /** * LDAP分页查询,使用时需要异步统计返回结果集的总行数 * @author sxl * */ public class LdapSearch { /** * 根据条件查找指定DN的条目下的一层所有属性 * * @param dn * 要查询的BaseDN名称 * @param filter * 要查询的过滤字符串 * @param returnedAtts * 要查找的属性 * @param start * 开始行 * @param limit * 分页大小,如果为-1,则返回结果集的总行数 * @return 符合查询结果的List */ public static List searchContextOneByPage(String dn, String filter, String[] returnedAtts, int start, int limit){ DirContext context = getDirContext("url","username","password"); if(context == null) return null; // 实例化一个搜索器 SearchControls constraints = new SearchControls(); // 设置搜索器的搜索范围为ONELEVEL constraints.setSearchScope( SearchControls.ONELEVEL_SCOPE); // 设置返回的属性 if (returnedAtts != null) { constraints.setReturningAttributes(returnedAtts); } try { if (filter == null || filter.trim().equals("")) { filter = "objectclass=*"; } NamingEnumeration<SearchResult> results = context.search(dn, filter, constraints); context.close(); return searchPage(results,start,limit); } catch (NamingException ex) { ex.printStackTrace(); return null; } } /** * 分页查询 * @param resultList * @param results * @throws NamingException */ private static List searchPage(NamingEnumeration<SearchResult> results,int start,int limit) throws NamingException { List resultList = new ArrayList(); int row = 0; boolean flag = false; while (results != null && results.hasMore()) { SearchResult si = results.next();// 取一个条目 if(limit == -1)//如果limit==-1,只统计总行数 row++; else { if(row++ == start) flag = true;//从start行开始取数据 Attributes attrs = si.getAttributes(); if (attrs != null && flag) { Map resultRowMap = new HashMap();// 一行数据 for (NamingEnumeration ae = attrs.getAll(); ae.hasMoreElements();) { Attribute attr = (Attribute) ae.next();// 获取一个属性 String attrId = attr.getID(); Enumeration vals = attr.getAll(); if (vals != null) { ArrayList valList = new ArrayList(); while (vals.hasMoreElements()) { Object obj = vals.nextElement(); if (obj instanceof String) { String _value = (String) obj; valList.add(_value); } else { valList.add(obj); } } resultRowMap.put(attrId, valList); } } resultList.add(resultRowMap); if(resultList.size() == limit){ break; } } } } results.close(); if(limit == -1)//如果limit为-1,则只返回总行数 resultList.add(row); return resultList; } /** * 从LDAP中取得一个连接 * @return DirContext */ private static DirContext getDirContext(String url,String userdn,String password){ Properties mEnv = new Properties(); mEnv.put(Context.AUTHORITATIVE, "true"); mEnv.put("com.sun.jndi.ldap.connect.pool", "false"); mEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); mEnv.put(Context.PROVIDER_URL, url); mEnv.put("com.sun.jndi.ldap.connect.timeout","3000"); mEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); mEnv.put(Context.SECURITY_PRINCIPAL, userdn); mEnv.put(Context.SECURITY_CREDENTIALS, password); DirContext ctx = null; try { ctx = new InitialLdapContext(mEnv, null); } catch (NamingException ex) { ex.printStackTrace(); if(ctx != null) try { ctx.close(); } catch (NamingException e) { e.printStackTrace(); } } return ctx; } }
使用时,传递start和limit作为分页的参数,这样在迭代结果集的时候进行判断,从start开始一直取limit个元素结束。
但是,这里有一个前提条件,我们要异步来统计结果集的总行数,传递limit为-1。以EXT为例,我们覆盖Ext.PagingToolbar这个类里的一些函数,保存为myPagebar.js。
(function (){ var total = 0; var T = Ext.Toolbar; Ext.PagingToolbar.prototype.setTotalCount = function(num){ total = num; } Ext.PagingToolbar.prototype.getPageData = function(){ if(total == 0){ this.inputItem.setDisabled(true); }else{ this.inputItem.setDisabled(false); this.last.setDisabled(false); } return { total : total, activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize), pages : Math.ceil(total/this.pageSize) }; } Ext.PagingToolbar.prototype.onLoad = function(store, r, o){ if(!this.rendered){ this.dsLoaded = [store, r, o]; return; } var p = this.getParams(); this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0; var d = this.getPageData(), ap = d.activePage, ps = d.pages; this.afterTextItem.setText(String.format(this.afterPageText, d.pages)); this.inputItem.setValue(ap); this.first.setDisabled(ap == 1); this.prev.setDisabled(ap == 1); this.next.setDisabled(ap == ps); //this.last.setDisabled(ap == ps); this.refresh.enable(); this.updateInfo(); this.fireEvent('change', this, d); } Ext.PagingToolbar.prototype.updateInfo = function(){ if(this.displayItem){ var count = this.store.getCount(); var msg = count == 0 ? this.emptyMsg : String.format( this.displayMsg, this.cursor+1, this.cursor+count, total ); this.displayItem.setText(msg); } } Ext.PagingToolbar.prototype.changePage = function(page){ this.doLoad(((page-1) * this.pageSize).constrain(0, total)); } Ext.PagingToolbar.prototype.moveLast = function(){ var extra = total % this.pageSize; this.doLoad(extra ? (total - extra) : total - this.pageSize); } })();
在jsp里引入myPagebar.js后,按照正常的方式使用Ext.PagingToolbar就可以了。
这样,在使用Ext.grid.GridPanel来显示数据之前,先使用Ajax去后台统计总行数,传递参数里增加start:1,limit:-1。
在Ajax成功返回后,调用Ext.PagingToolbar.prototype.setTotalCount(totalRow);同时,Ext.grid.GridPanel的store会去后台load数据,传给后台的参数包括start:1,limit:50,表示取第一页的50行数据。这样就实现了后台分页的效果。
如果数据很多,统计总行数会耗时较长,这时Ext.grid.GridPanel上显示的总页数为0,但是可以点击<下一页>,继续访问下一页的数据。直到总行数统计完成后,才能看到总页数,才能翻到最后一页。
这种方式避免了数据过多时的内存溢出问题,也提高了数据的访问速度,最起码是页数比较靠前的数据的访问速度。友好度也要好很多。
评论
2 楼
softfn
2014-01-15
没解决本质问题 你这个只是为了页面分页而已
1 楼
tangmin823
2013-02-19
这个根本算不上LDAP分页查询啊,不也是先查询出所有的记录吗?!
发表评论
-
使用zookeeper实现分布式共享锁
2013-04-13 15:59 2558分布式系统中经常需要协调多进程,多个jvm,或者多台机器之间 ... -
WebService:Axis客户端调用需要身份验证的CXF服务
2012-11-24 12:05 7025CXF服务端代码: 1、web.xml配置 < ... -
使用axis轻松调用Webservice
2012-11-10 13:15 21855使用axis1.4调用webservice有两种简单的方式: ... -
执行java程序时如何引用依赖的jar
2012-11-10 12:38 1749在执行java程序时我们可以通过-Djava.ext.dirs ... -
Log4j简单实用配置
2012-10-27 12:22 3629#A1为控制台输出,A2为文件输出,R为文件输出,并且按 ... -
JavaNIO处理长连接
2012-09-12 21:04 14043之前在IBM的网站上看到过一篇介绍NIO的文章,收获很大。但文 ... -
Int和byte数组之间的转换
2012-08-27 20:25 18744有时候和C的程序通信的时候,我们在封装协议时,可能需要将Jav ... -
用闭锁测试HashMap的并发写入问题
2012-08-27 19:39 3619今天无意中看到以前写 ... -
并行计算框架的Java实现--系列三
2012-07-14 14:38 4104接上篇并行计算框架的Java实现--系列二 优化锁,之 ... -
并行计算框架的Java实现--系列二
2012-07-14 08:41 2892接上篇并行计算框架的J ... -
并行计算框架的Java实现--系列一
2012-07-14 07:38 3435最近的工作需要统计一些复杂的报表,为了提高效率,想用多线程去实 ... -
ant初探
2012-06-29 13:38 2865前些天和同事交流,他说ant非常好用,他一直在用,学习资料共享 ... -
基于事件的 NIO 多线程服务器
2012-06-27 17:06 1203JDK1.4 的 NIO 有效解决了原有流式 IO 存在的线程 ... -
Java NIO学习
2012-06-22 22:46 0端午节加班要开发一个SocketServer,需要承载1000 ... -
httpclient访问https服务,可以信任证书
2012-06-02 00:48 6804private HttpClient initHttpClie ... -
Java或Web工程中查找配置文件
2012-06-02 00:35 1029String path = ""; URL ... -
如何获取真实的终端IP
2011-11-24 11:16 1183在有Apache做负载均衡的时候使用request.getRe ... -
MANIFEST.MF的应用以及如何读取jar包外的log4j.properties
2011-11-22 18:21 34MANIFEST.MF是jar文件的配置文件,在用eclips ... -
java实现的telnet协议
2011-10-02 17:14 7339package telnet; import j ... -
很好用的java反编译工具
2011-10-02 16:36 1205可以反编译单个文件,也可以反编译整个jar
相关推荐
NULL 博文链接:https://zhao-weigang.iteye.com/blog/2008377
Spring LDAP。 官网 Spring LDAP API。 Spring LDAP 开发文档。
基于RuoYi框架,使用的是ruoyi前后端不分离的版本,实现对LDAP的整合 基于RuoYi框架,使用的是ruoyi前后端不分离的版本,实现对LDAP的整合 基于RuoYi框架,使用的是ruoyi前后端不分离的版本,实现对LDAP的整合 基于...
LDAP协议是Internet中用于数据查询访问的重要协议,在PKI基础设施中,LDAP可用于证书和CRL的查询下载,...结合了LDAP协议标准和PKI实现的具体要求,提出了一种基于关系数据库的LDAP服务器的实现方式,实现了LDAP的查询操作。
ldap域信息查询工具
活动目录ladp自定义查询语法和过滤器......
LDAP 查询指定目录-所有活动用户
LDAP RFC2254LDAP查询过滤器的字符串表示法,中文版。 LDAPChina经典原创。
rar包:一个Web工程, 主要有,利用Spring-ldap对LDAP的基本操作(查询,增删改);Extjs实现的对Ldap的树状结构的显示,结构有点类似Softerra LDAP;一个测试类。 pdf:spring-ldap-reference.pdf Extjs.pdf ...
RFC2254LDAP查询过滤器的字符串表示法中文版
可以输入中文属性值 可以输入中文属性值 可以输入中文属性值可以输入中文属性值可以输入中文属性值 可以输入中文属性值 可以输入中文属性值
用sql语句的方式操作ldap,可以对ldap的数据进行查询、删除、修改Jsp/Servlet
基于java的开发源码-开源LDAP浏览器 JXplorer.zip 基于java的开发源码-开源LDAP浏览器 JXplorer.zip 基于java的开发源码-开源LDAP浏览器 JXplorer.zip 基于java的开发源码-开源LDAP浏览器 JXplorer.zip 基于java的...
从Google Doc搬运过来的,希望能帮助到一些人。
LdapAdmin-1.8.3 win64下的ldap可视化管理工具,非常好用哦。
基于SSL的ldap安全访问AD认证,对密码进行加密认证!
perl语言写的ldap查询指定域用户的信息,可以用来搜索相应ldap域用户信息,以此进行相关处理。
基于LDAP统一用户管理系统的研究与应用,内容充实。基于LDAP统一用户管理系统的研究与应用,内容充实。
基于LDAP认证和MOM的分布式会议系统
LDAP入門,LDAP入門LDAP入門LDAP入門LDAP入門LDAP入門LDAP入門LDAP入門LDAP入門LDAP入門LDAP入門LDAP入門