无法使LDAP VirtualListView正常工作

时间:2016-10-18 21:50:38

标签: java ldap jndi apacheds

我无法让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

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

抱歉,该链接无效。它对我有用。这是我正在使用的代码示例,它始终返回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;
  }

}

1 个答案:

答案 0 :(得分:-1)

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

由于我的客户使用的是SunOne LDAP服务器,我想我会尝试一下。 SunOne在2000年代早期只存在了几年,但直到2011年才被支持为Oracle目录服务。您可以从他们的网站Oracle site for download下载它。查找Oracle Directory Server Enterprise Edition(11.1.1.7.0)。我相信您需要Oracle开发人员登录。安装说明在Installation Documentation

Oracle目录服务是我在有限搜索中找到的唯一一个正确支持VLV控制的LDAP服务器。

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

这是我发现的,如果我错了,我很想听听其他LDAP服务器如何支持VLV进行分页。对于任何看过这篇文章的人都谢谢!