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

获取LDAP单条记录时触发ConverterNotFoundException问题排查

解决Spring Data LDAP GET单条记录时String转Name的转换器异常

你遇到的这个问题本质是Spring Data REST的转换服务没有识别到Spring LDAP自带的StringToNameConverter,导致在把URL路径里的DN(区分名)字符串转换成javax.naming.Name类型时找不到合适的转换器,触发了ConverterNotFoundException。下面给你几个实用的解决方案:

方案一:全局注册String到Name的转换器

最彻底的方式是把String转Name的转换器注册到Spring的全局转换服务里,让Spring Data REST能自动找到它。你可以创建一个配置类来实现:

import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.ldap.support.LdapUtils;

import javax.naming.Name;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        // 注册自定义转换器:String -> Name
        registry.addConverter(String.class, Name.class, source -> LdapUtils.newLdapName(source));
    }
}

或者如果你更倾向于Spring Data REST的专属配置,也可以实现RepositoryRestConfigurer:

import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer;
import org.springframework.core.convert.converter.Converter;
import org.springframework.ldap.support.LdapUtils;

import javax.naming.Name;

@Configuration
public class RestRepositoryConfig implements RepositoryRestConfigurer {

    // 把转换器注册为Bean,让Spring自动识别
    @Bean
    public Converter<String, Name> stringToNameConverter() {
        return LdapUtils::newLdapName;
    }
}

方案二:在Repository中手动处理ID转换

如果不想全局注册转换器,也可以在你的LdapUserRepository里重写findById方法,手动把传入的String类型ID转换成Name:

import org.springframework.ldap.support.LdapUtils;
import org.springframework.stereotype.Repository;
import javax.naming.Name;
import java.util.Optional;

@Repository
public interface LdapUserRepository extends LdapRepository<LdapUser> {
    LdapUser findByCommonName(String commonName);
    List<LdapUser> findByCommonNameContainingIgnoreCase(String commonName);

    // 重写findById,手动转换String到Name
    @Override
    default Optional<LdapUser> findById(String id) {
        Name dn = LdapUtils.newLdapName(id);
        return findById(dn);
    }
}

不过要注意,Spring Data REST可能在调用这个方法前还是会尝试自动转换ID,所以这个方案有时候不如方案一稳定。

方案三:调整实体类的ID类型(可选)

如果你的项目允许调整实体类,也可以把@Id字段的类型从Name改成String,这样就不需要转换器了:

@Entry(objectClasses = {"inetOrgPerson", "organizationalPerson", "person", "top"})
@Getter @Setter @NoArgsConstructor @AllArgsConstructor
public class LdapUser {
    @Id
    private String distinguishedName;

    // 其他属性保持不变...

    // 可选:添加方法方便转换为Name类型,供LDAP操作使用
    public Name getDnAsName() {
        return LdapUtils.newLdapName(distinguishedName);
    }
}

这时候需要把Repository的泛型改成LdapRepository<LdapUser, String>,如果你的项目已经有很多基于Name的代码,这个方案的改动成本会比较高,所以优先考虑前两个方案。

验证效果

配置完成后重启应用,再访问/ldapUsers/cn=Katherine%20Ito,ou=Peons,应该就能成功返回单条用户记录了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:38:34