You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot使用LdapTemplate从AD分页查询超1000条记录时Cookie为空

解决方案

1. 让LdapTemplate使用手动配置的上下文

你现在手动创建了LdapContext并设置了分页控件,但ldapTemplate.search()默认会用自己管理的上下文,根本没用到你配置的这个。必须改用带上下文参数的重载方法:

修改查询代码中的search调用:

// 替换原search方法,传入手动创建的ldapContext
ldapTemplate.search(ldapContext, "", filter.encode(), new AbstractContextMapper<String>() {
    @Override
    protected String doMapFromContext(DirContextOperations ctx) {
        return ctx.getNameInNamespace();
    }
}).forEach(results::add);

2. 手动注册分页响应控件的解码器

JDK默认不会自动解码PagedResultsResponseControl,所以你拿不到响应控件。在创建LdapContext后,添加注册解码器的代码:

LdapContext ldapContext = (LdapContext) ldapTemplate.getContextSource().getReadOnlyContext();
// 注册响应控件解码器
ldapContext.addToEnvironment(
    "java.naming.ldap.control.response",
    "1.2.840.113556.1.4.319:com.sun.jndi.ldap.ctl.PagedResultsResponseControl"
);
// 再设置分页请求控件
ldapContext.setRequestControls(new Control[] { 
    new PagedResultsControl(1000, cookie, Control.CRITICAL) 
});

3. 优化上下文复用(可选)

没必要每次循环都创建新上下文,复用一个上下文重置控件即可,减少资源消耗:

LdapContext ldapContext = (LdapContext) ldapTemplate.getContextSource().getReadOnlyContext();
try {
    byte[] cookie = null;
    // 先注册解码器
    ldapContext.addToEnvironment(
        "java.naming.ldap.control.response",
        "1.2.840.113556.1.4.319:com.sun.jndi.ldap.ctl.PagedResultsResponseControl"
    );
    do {
        ldapContext.setRequestControls(new Control[] { 
            new PagedResultsControl(1000, cookie, Control.CRITICAL) 
        });
        // 使用带上下文的search方法
        ldapTemplate.search(ldapContext, "", filter.encode(), new AbstractContextMapper<String>() {
            @Override
            protected String doMapFromContext(DirContextOperations ctx) {
                return ctx.getNameInNamespace();
            }
        }).forEach(results::add);
        
        // 获取分页Cookie
        Control[] controls = ldapContext.getResponseControls();
        cookie = null;
        if (controls != null) {
            for (Control control : controls) {
                if (control instanceof PagedResultsResponseControl) {
                    cookie = ((PagedResultsResponseControl) control).getCookie();
                }
            }
        }
    } while (cookie != null && cookie.length > 0);
} finally {
    ldapContext.close();
}

4. 检查搜索范围和AD配置

  • 确认搜索范围是否正确:当前搜索路径是空字符串,可能只查了base节点,建议指定具体OU或者用SearchControls设置SUBTREE_SCOPE:
    SearchControls searchControls = new SearchControls();
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    // 把searchControls传入search方法
    ldapTemplate.search(ldapContext, "", filter.encode(), searchControls, mapper);
    
  • 确认AD服务器分页功能开启:AD默认支持分页,但部分环境可能被管理员禁用,需要联系运维确认。

内容的提问来源于stack exchange,提问作者sergiopf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 13:33:14