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

UnboundID LDAP SDK Java异步搜索如何简化获取SearchResultEntry?

LDAP异步获取条目简化实现方案

问题背景

基于LDAP SDK异步API实现按DN获取条目功能时,初始代码返回的SearchResult不符合预期的SearchResultEntry类型,用Java并发工具实现的版本可用但显得繁琐,希望找到更简洁的方式。

初始代码:

val searchRequest = SearchRequest(
    EmptyAsyncListener(),
    dn,
    SearchScope.BASE,
    DereferencePolicy.NEVER,
    1,
    0,
    false,
    Filter.createPresenceFilter("objectClass"),
    *attributes,
)
val asyncRequestId = getConnection().asyncSearch(searchRequest)
val ldapResult = asyncRequestId.get()

现有可用但繁琐的实现:

val latch = CountDownLatch(1)
val ref = AtomicReference<SearchResultEntry>()
val searchRequest = SearchRequest(
    SimpleAsyncListener(latch, ref),
    dn,
    SearchScope.BASE,
    DereferencePolicy.NEVER,
    1,
    0,
    false,
    Filter.createPresenceFilter("objectClass"),
    *attributes,
)
getConnection().asyncSearch(searchRequest)
latch.await()
val entry = ref.get()

监听器代码:

class SimpleAsyncListener(private val latch: CountDownLatch, private val ref: AtomicReference<SearchResultEntry>) :
    AsyncSearchResultListener {

    override fun searchEntryReturned(@NotNull searchEntry: SearchResultEntry) {
        ref.set(searchEntry)
        latch.countDown()
    }

    override fun searchReferenceReturned(
        @NotNull searchReference: SearchResultReference
    ) {
        // No implementation required.
    }

    override fun searchResultReceived(
        @NotNull requestID: AsyncRequestID,
        @NotNull searchResult: SearchResult
    ) {

    }
}

简化实现方案

方案一:直接从SearchResult提取条目

由于使用的是SearchScope.BASE(仅查询目标DN本身),SearchResult的searchEntries集合只会包含目标条目,无需额外监听器或并发工具:

val searchRequest = SearchRequest(
    dn,
    SearchScope.BASE,
    DereferencePolicy.NEVER,
    1,
    0,
    false,
    Filter.createPresenceFilter("objectClass"),
    *attributes,
)
val asyncRequestId = getConnection().asyncSearch(searchRequest)
val searchResult = asyncRequestId.get()
val entry = searchResult.searchEntries.firstOrNull()

方案二:用Kotlin协程CompletableDeferred简化监听器

如果需要保留异步监听器模式,用Kotlin协程的CompletableDeferred替代CountDownLatch和AtomicReference,代码更简洁且贴合Kotlin异步风格:

fun getEntryAsync(dn: String, vararg attributes: String): CompletableDeferred<SearchResultEntry?> {
    val deferred = CompletableDeferred<SearchResultEntry?>()
    val searchRequest = SearchRequest(object : AsyncSearchResultListener {
        override fun searchEntryReturned(searchEntry: SearchResultEntry) {
            deferred.complete(searchEntry)
        }

        override fun searchReferenceReturned(searchReference: SearchResultReference) {
            // 按需处理搜索引用
        }

        override fun searchResultReceived(requestID: AsyncRequestID, searchResult: SearchResult) {
            // 无条目返回时补全null
            if (!deferred.isCompleted) {
                deferred.complete(null)
            }
        }
    }, dn, SearchScope.BASE, DereferencePolicy.NEVER, 1, 0, false, Filter.createPresenceFilter("objectClass"), *attributes)
    
    getConnection().asyncSearch(searchRequest)
    return deferred
}

// 使用示例
runBlocking {
    val entry = getEntryAsync("cn=test,dc=example,dc=com").await()
}

方案说明

  • 方案一最简洁:完全利用BASE搜索的特性,直接从异步返回的SearchResult中提取目标条目,避免了多余的并发工具类。
  • 方案二更适合需要自定义异步回调逻辑的场景:用Kotlin协程API替代Java并发工具,代码更紧凑,还能妥善处理无条目返回的边界情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 12:15:58