无法让 LDAP VirtualListView 工作

Can not get LDAP VirtualListView to work

我无法让 VLV 控制正常工作。我正在使用 ApacheDS 2.0.0 并使用 Java JNDI 与 Sun 的 ldapbp-1.0.jar 进行通信。当被查询时,服务器说它支持 VLV 控制。我没有收到任何错误,但是我设置了搜索并返回了所有结果而不是一个子集。我设置了一个新的 ApacheDS 实例,其中有 10 个用户。我总是得到全部 10 个结果。

我也得到了一个 SortResponseControl 而不是 VirtualListViewResponseControl。

我见过很多例子,我基本上就是在做它们。我逐字记录了这个代码示例,只是更改了连接信息和搜索条件,但我仍然遇到同样的问题。 Post from LDAP Pro forum

我为 VirtualListViewControl 尝试过的一些参数是:

    new VirtualListViewControl(1, 0, 0, 19, Control.CRITICAL);  // original - gets all
    new VirtualListViewControl(1, 10, 1, 2, Control.CRITICAL);  // target offset -gets all
    new VirtualListViewControl(20, 3, Control.CRITICAL);  // target percentage - gets all
    new VirtualListViewControl("Tryit4", 3, Control.CRITICAL);  // target value, view size - gets all
    new VirtualListViewControl("Tryit4", 2, 1, Control.CRITICAL);  // target value, before count, after count

我一定是做错了什么,但我看不出是什么。任何帮助,将不胜感激。 谢谢

抱歉,link 不起作用。它对我有用。这是我正在使用的代码示例,它总是 returns SortResponseControl 和所有 LDAP 条目。

/**
 * 
 * VLVJndiClient.java
 * Sample code to demostrate how Virtual List View (VLV) Control works.
 * Note:
 *       1) Note: JNDI Boost package is required for this example to run.
 *       2) VLV Control MUST be used in conjunction with Sort Control.
 *       Otherwise, you will be braced by:  [LDAP: error code 60 - VLV Control]
 *    3) SunOne Directory Server supports VLV & Microsoft supports VLV since AD2003 
 * 
 */

import java.util.Hashtable;
import java.io.*;

import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;

import com.sun.jndi.ldap.ctl.VirtualListViewControl;
import com.sun.jndi.ldap.ctl.VirtualListViewResponseControl;
import com.sun.jndi.ldap.ctl.SortControl;

public class VLVJndiClientShort 
{

  static final String  VLV_CONTROL_OID = "2.16.840.1.113730.3.4.9";

  public static void main(String[] args) throws IOException 
  {
      Hashtable env = new Hashtable();

      env.put(Context.INITIAL_CONTEXT_FACTORY, 
                  "com.sun.jndi.ldap.LdapCtxFactory");

      env.put(Context.PROVIDER_URL, "ldap://172.16.2.23:10389");
      env.put(Context.SECURITY_AUTHENTICATION, "simple");
      env.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
      env.put(Context.SECURITY_CREDENTIALS, "test");

      try {
          /* Create initial context with no connection request controls */
          LdapContext ctx = new InitialLdapContext(env, null);

          /* Query the server to see if the VLV Control is supported */ 
          if (!isVLVControlSupported(ctx)){
               System.out.println(
             "The server does not support Virtual List View (VLV) Control.");
               System.exit(1);
          }

          /* Sort Control is required for VLV to work */
          SortControl sctl = new SortControl(
               new String[]{"cn"}, // sort by cn 
                Control.CRITICAL
            );

          /* VLV that returns the first 20 answers 0 to 19 changed 19 to 2 */
          VirtualListViewControl vctl = 
//                new VirtualListViewControl(1, 0, 0, 19, Control.CRITICAL);  // original - gets all
//                new VirtualListViewControl(1, 10, 1, 2, Control.CRITICAL);  // target offset, list size, before count, after count, criticality  - gets all
//                  new VirtualListViewControl(20, 3, Control.CRITICAL);  // target percentage, view size, criticality - gets all
//                  new VirtualListViewControl("Tryit4", 3, Control.CRITICAL);  // target value, view size, criticality - gets all
                  new VirtualListViewControl("Tryit4", 2, 1, Control.CRITICAL);  // target value, before count, after count, criticality

          /* Set context's request controls */ 
          ctx.setRequestControls(new Control[]{sctl, vctl}); // returns only a sorted control but no VLV control

          /* Perform search */
          NamingEnumeration answer = 
                  ctx.search("dc=mir3,dc=example,dc=com", "(objectclass=*)", null);

          /* Enumerate search results */
          while (answer.hasMore()) {
              SearchResult si = (SearchResult)answer.next();
              System.out.println(si.getName());
          }

          /* examine the response controls (if any) */
          printControls(ctx.getResponseControls());

          ctx.close();

      } catch (NamingException e) {
            e.printStackTrace();
      }
  }

  static void printControls(Control[] controls) 
  {
      if(controls == null){
          System.out.println("No response controls");
          return;
      }

      for(int j = 0; j < controls.length; j++) {
          if(controls[j] instanceof SortResponseControl){
              SortResponseControl src = (SortResponseControl)controls[j];
              if (src.isSorted()) {
                  System.out.println("Sorted-Search completed successfully");
              } else {
                  System.out.println(
                      "Sorted-Search did not complete successfully: error (" +
                      src.getResultCode() + ") on attribute '" + 
                      src.getAttributeID() + "'");
              }
          }else if(controls[j] instanceof VirtualListViewResponseControl){
              VirtualListViewResponseControl vlv =
                      (VirtualListViewResponseControl)controls[j];
              if (vlv.getResultCode() == 0) {
                  System.out.println("Sorted-View completed successfully");
                  System.out.println("TargetOffset: " + vlv.getTargetOffset());
                  System.out.println("ListSize: " + vlv.getListSize());
              } else {
                  System.out.println("Sorted-View did not complete successfully: " 
                               + vlv.getResultCode());
              }
          } else {
              System.out.println("Received control: "+ controls[j].getID());
          }
      }
  }

  /**
   * Is VLV Control supported?
   *
   * Query the rootDSE object to find out if VLV Control
   * is supported.
   */
  static boolean isVLVControlSupported(LdapContext ctx) 
    throws NamingException
  {
      SearchControls ctl = new SearchControls();
      ctl.setReturningAttributes(new String[]{"supportedControl"});
      ctl.setSearchScope(SearchControls.OBJECT_SCOPE);

      /* search for the rootDSE object */
      NamingEnumeration results = ctx.search("", "(objectClass=*)", ctl);

      while(results.hasMore()){
          SearchResult entry = (SearchResult)results.next();
          NamingEnumeration attrs = entry.getAttributes().getAll();
          while (attrs.hasMore()){
              Attribute attr = (Attribute)attrs.next();
              NamingEnumeration vals = attr.getAll();
              while (vals.hasMore()){
                  String value = (String) vals.next();
                  if (value.equals(VLV_CONTROL_OID))
                        return true;
              }
          }
      }
      return false;
  }

}

似乎没有人对此有任何意见,但我会告诉你我发现了什么。如上所述,我试图让 VLV 在 OpenLDAP 和 apacheDS 上工作。当被查询时,服务器说它们支持该控件,但是当您使用它时,您会取回所有条目,而不是请求的子集。

因为我的客户使用的是 SunOne LDAP 服务器,所以我想我会尝试一下。 SunOne 在 2000 年代初期仅出现了几年,但直到 2011 年才作为 Oracle 目录服务得到支持。您可以从他们的网站 Oracle site for download. Look for the Oracle Directory Server Enterprise Edition (11.1.1.7.0). I believe you need an Oracle Developers login. The installation instructions are here Installation Documentation.

下载它

Oracle 目录服务是我在有限的搜索中找到的唯一正确支持 VLV 控制的 LDAP 服务器,正如它所记录的那样。

请注意,服务器会说它们支持 VLV,但当它们也支持分页搜索时,VLV 将无法正确实施。

这是我发现的,如果我有误,我很想听听其他 LDAP 服务器如何支持 VLV 进行分页。对于看过此内容的任何人 post 谢谢!