歡迎您光臨本站 註冊首頁

有人在這裡討論一下,javax.naming.ldap.PagedResultsControl ,ldap分頁的問題嗎?

sun的jndi中提供的分頁功能javax.naming.ldap.PagedResultsControl ,好像用起來不太爽,不知道大家怎麼處理的,
比如,我是在b/s模式中進行分頁,可能是我理解的錯誤,這個介面的分頁好像是從一個上一個查詢中返回的結果中取得cookie才能翻到下一頁,但是在b/s模式中,從第一頁直接翻到第N頁,哪不是要先得到N-1個cookie??這樣每次從頭翻到尾還有什麼意義呢? 哪位仁兄,達人,可以切磋一下?

[ 本帖最後由 wangbaohua 於 2007-1-23 19:01 編輯 ]
《解決方案》

自己先頂一個,目前好像目錄的分頁功能並不是所有的伺服器都技持,
大家知道技持分頁功能的目錄服務有哪些??

雖然同為sun自己的東西,netscape.ldap.controls.LDAPVirtualListControl,跟他自己標準的
javax.naming.ldap.PagedResultsControl 用法好像就完全不一樣,前者只要用
LDAPVirtualListControl(int startIndex, int beforeCount, int afterCount, int contentCount)
就可以了,
《解決方案》

關注!!
《解決方案》

http://www3.ietf.org/proceedings/03mar/I-D/draft-ietf-ldapext-ldapv3-vlv-09.txt,
       LDAP Extensions for Scrolling View Browsing of Search Results
http://www.ietf.org/rfc/rfc2696.txt,
     LDAP Control Extension for Simple Paged Results Manipulation

顯然這兩個東西是不一樣的,前一個簡稱vlv,這樣來看sun的標準介面對於開發來說提供的支持還不是很全面,我想各個目錄服務自己提供的sdk應該都有類似這樣功能的實現吧! 比較了一下,實現了vlv的介面可能在功能上更好用, 但是sun提供的提介面從方向上來說,更可能是一種標準,只是不知道他們什麼時候提供vlv功能。
《解決方案》

下載了所有的jndi的擴展包下來,一個一個看過,終於發現sun的vlv介面在ldapbp-1_0.zip(LDAP Booster Pack 1.0 Release)中
《解決方案》

做一個分頁的例子,運行成功,但是速度是非常的慢,我在50000條數據中做分頁,每頁大小才20,
但是每查詢一次好像要48875ms,基本上屬於不可用的狀態。

伺服器環境是sun one directory server 5.2 ,win2003,

暫時不知道是什麼原因,導致慢,因為就算我把50000條記錄全部輸出花的時間也只有這個時間的零頭。
有人懂這個原理的么??

import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
import java.io.IOException;
import java.util.*;
import com.sun.jndi.ldap.ctl.*;

public class PageMain {

        public static void main(String[] args) {


                Hashtable m_env = new Hashtable(5, 0.75f);
                LdapContext m_Ctx;
                m_env.put(Context.INITIAL_CONTEXT_FACTORY,
                                "com.sun.jndi.ldap.LdapCtxFactory");
                m_env.put("java.naming.ldap.version", "3");
                m_env.put(Context.PROVIDER_URL, "ldap://192.168.1.153:12345");
                m_env.put(Context.SECURITY_AUTHENTICATION, "simple");
                m_env.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");
                m_env.put(Context.SECURITY_CREDENTIALS,"12345678");

                try{
                        m_Ctx = new InitialLdapContext(m_env, null);
                        boolean b = true;
                        int counter = 0;
                        int listSize = 0;
                        int i = 0;
                        int nTargetOffset = 1;
                        int nPageSize = 20;
                        while (b) {
                               
                                VirtualListViewControl vctl
                                = new VirtualListViewControl(nTargetOffset, 0, 0, nPageSize, Control.CRITICAL);
                                javax.naming.ldap.SortControl sctl
                                =new javax.naming.ldap.SortControl(new String[] { "cn" },Control.CRITICAL);
                               
                                m_Ctx.setRequestControls(new Control[] { sctl, vctl });

                                SearchControls constraints = new SearchControls();
                                constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
                                String[] retAtt = { "cn" };
                                constraints.setReturningAttributes(retAtt);
                               
                                String searchCondition = "(objectclass=inetOrgPerson)";
                               
                                System.out.println("-----------"+i+"-----------");

                                i++;
                                NamingEnumeration results =
                                        m_Ctx.search("dc=com", searchCondition,constraints);
                                System.out.println(m_Ctx);
                                int subcounter = 0;
                                if (results != null) {
                                        System.out.println("---------println results-----------");
                                        while (results.hasMoreElements()) {
                                                subcounter++;
                                                SearchResult si = (SearchResult) results.nextElement();
                                                counter++;
                                                System.out.println(si.getName());
                                        }
                                        System.out.println(searchCondition + " returned "+ subcounter);
                                        if (subcounter == 0){
                                                b = false;
                                                }
                                } else{
                                        System.out.println(searchCondition+ " did not match with any!!!");
                                }

                                System.out.println("------------------NEW PAGE NO. " + i);
                                nTargetOffset += subcounter; // nPageSize; //subcounter;
                        }
               
                } catch (NamingException e) {
                        e.printStackTrace();
                        System.out.println(e);
                }catch (IOException ex) {
                        System.out.print(ex);
                }
               
        }

}
《解決方案》

上面同樣的分頁功能在 openldap 2.2.*中,執行不能成功,
報錯:
javax.naming.OperationNotSupportedException: ; remaining name ……
我沒有看到openldap說支持vlv,是不是它就不支持。
《解決方案》

終於採用在 netscape.ldap 的sdk中提供的vlv方法分頁成功,速度還不錯,

只是留下幾個疑問,如果把jndi比作jdbc,哪么看來各個目錄對jndi的支持還不夠,

包括sun自己。如果真要做什麼開發如果不用jndi可能使程序失去復用性。

目前我在做一個目錄的應用,在選擇目錄伺服器上,和採用的開發介面上,正在猶豫中……

現在我的基本想法,就是基本netscape 和它自己的sdk來做,因為我不是做產品,

專用也就專用了,我現在想做一些基本的封裝,把邏輯層和目錄操作區分一下。

也試過spring的ldap,沒多看,基為它是基於jndi的所以還是不太放心,

   另:第一次發帖,發現好像自言自語,好不凄涼……,希望對大家有些幫助
《解決方案》

回復 8樓 wangbaohua 的帖子

我也有同感,之前寫了一個spring ldap分頁的測試用例,可是怎麼都跑不起來,鬱悶。
現將代碼貼出來,請大俠指點一下:
package com.cvicse.sso.console.dao;

import javax.naming.directory.SearchControls;

import junit.framework.TestCase;

import org.springframework.ldap.CollectingNameClassPairCallbackHandler;
import org.springframework.ldap.support.control.PagedResultsCookie;
import org.springframework.ldap.support.control.PagedResultsRequestControl;

import com.cvicse.sso.console.dao.ldap.LdapTemplateExtend;
import com.cvicse.sso.console.dao.ldap.CAASUserAttributesMapper;

public class LdapTemplatePagedSearchITest extends TestCase {

        private LdapTemplateExtend tested;

        // LDAP contains 5 persons matching the filter. Page size is 3.
        // Expects two batches of 3 and 2 persons respectively.
        public void testPagedResult() {
                SearchControls searchControls = new SearchControls();
                searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
                String base = "dc=cvicse,dc=com";
                String filter = "(&(objectclass=person)(cn=zhouzhou))";
                CAASUserAttributesMapper mapper = new CAASUserAttributesMapper();
                CollectingNameClassPairCallbackHandler handler = tested.new AttributesMapperCallbackHandler(
                                mapper);

                PagedResultsRequestControl requestControl;
                requestControl = new PagedResultsRequestControl(3);
                tested.search(base, filter, searchControls, handler, requestControl);
                PagedResultsCookie cookie = requestControl.getCookie();
                assertNotNull("Cookie should not be null yet", cookie.getCookie());
                assertEquals(3, handler.getList().size());

                // Prepare for second and last search
                requestControl = new PagedResultsRequestControl(3, cookie);
                tested.search(base, filter, searchControls, handler, requestControl);
                cookie = requestControl.getCookie();
                assertNull("Cookie should be null now", cookie.getCookie());
                assertEquals(5, handler.getList().size());
        }

}
《解決方案》

關注中.....

[火星人 ] 有人在這裡討論一下,javax.naming.ldap.PagedResultsControl ,ldap分頁的問題嗎?已經有743次圍觀

http://coctec.com/docs/service/show-post-12981.html