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
相关产品推荐
相关产品推荐

