【问题标题】:Spring LDAP AD paging support not working - LDAP: error code 12 - 00000057: LdapErr: DSID-0C09079ASpring LDAP AD 分页支持不起作用 - LDAP:错误代码 12 - 00000057:LdapErr:DSID-0C09079A
【发布时间】:2020-04-27 21:08:05
【问题描述】:

当尝试运行上面的代码时,我收到javax.naming.OperationNotSupportedException 的消息: [LDAP: error code 12 - 00000057: LdapErr: DSID-0C09079A, comment: Error processing control, data 0, v2580]

成功检索到第一页,仅在第二次循环迭代时抛出异常。

public void pagedResults() {
    PagedResultsCookie cookie = null;
    SearchControls searchControls = new SearchControls();
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    int page = 1;
    do {
        logger.info("Starting Page: " + page);
        PagedResultsDirContextProcessor processor = new PagedResultsDirContextProcessor(20, cookie);

        List<String> lastNames = ldapTemplate.search("", initialFilter.encode(), searchControls, UserMapper.USER_MAPPER_VNT, processor);
        for (String l : lastNames) {
            logger.info(l);
        }
        cookie = processor.getCookie();
        page = page + 1;
    } while (null != cookie.getCookie());
}

但是,当我使用上述纯实现删除 Spring LDAP 时,它可以工作!

try {
        LdapContext ctx = new InitialLdapContext(env, null);

        // Activate paged results
        int pageSize = 5;
        byte[] cookie = null;
        ctx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, Control.CRITICAL) });
        int total;

        do {
            /* perform the search */
            NamingEnumeration results = ctx .search("",
                            "(&(objectCategory=person)(objectClass=user)(SAMAccountName=vnt*))",
                            searchCtls);

            /* for each entry print out name + all attrs and values */
            while (results != null && results.hasMore()) {
                SearchResult entry = (SearchResult) results.next();
                System.out.println(entry.getName());
            }

            // Examine the paged results control response
            Control[] controls = ctx.getResponseControls();
            if (controls != null) {
                for (int i = 0; i < controls.length; i++) {
                    if (controls[i] instanceof PagedResultsResponseControl) {
                        PagedResultsResponseControl prrc = (PagedResultsResponseControl) controls[i];
                        total = prrc.getResultSize();
                        if (total != 0) {
                            System.out.println("***************** END-OF-PAGE "
                                    + "(total : " + total
                                    + ") *****************\n");
                        } else {
                            System.out.println("***************** END-OF-PAGE "
                                    + "(total: unknown) ***************\n");
                        }
                        cookie = prrc.getCookie();
                    }
                }
            } else {
                System.out.println("No controls were sent from the server");
            }
            // Re-activate paged results
            ctx.setRequestControls(new Control[] { new PagedResultsControl(
                    pageSize, cookie, Control.CRITICAL) });

        } while (cookie != null);

        ctx.close();

    } catch (NamingException e) {
        System.err.println("PagedSearch failed.");
        e.printStackTrace();
    } catch (IOException ie) {
        System.err.println("PagedSearch failed.");
        ie.printStackTrace();
    }

有什么提示吗?

【问题讨论】:

    标签: active-directory paging spring-ldap


    【解决方案1】:

    LDAP 分页结果的坏处在于,它们只有在所有请求都使用相同的底层连接时才有效。 Spring LDAP 的内部为每个 LdapTemplate 操作获取一个新连接,除非您使用事务支持。

    确保将同一连接用于一系列 LDapTemplate 操作的最简单方法是使用事务支持,即为 Spring LDAP 配置事务并使用 Transactional 注释包装目标方法。

    【讨论】:

    【解决方案2】:

    我设法使上面的示例使用 SingleContextSource.doWithSingleContext 方法工作。

    但是我的场景不同,我的应用是面向服务的,分页结果和 cookie 应该发送到外部客户端,以便他决定是否请求下一页。

    据我所知,spring-ldap 不支持这种情况。我必须使用纯实现,以便在请求期间跟踪底层连接。事务支持和 SingleContextSource 一样有帮助,但在不同的请求中没有。

    @marthursson spring ldap 未来有没有计划支持这样的支持?

    【讨论】:

      【解决方案3】:

      我发现我可以使用您的第一个示例 (Spring),只要我在 ldapTemplate 配置中将 ignorePartialResultException 属性设置为 true 并按照建议将 @Transactional 放在我的方法上。

      【讨论】:

      • 是的,它解决了问题。您尝试过还是只是拖钓?
      【解决方案4】:

      你可以像这样替换ldapTemplateDirContext

      ldapTemplate.setContextSource(new SingleContextSource(ldapContextSource().getReadWriteContext()));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-03
        • 2019-10-13
        • 2014-04-02
        相关资源
        最近更新 更多