首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

封裝 JNDI 操作 LDAP 服務的工具類(三):LdapOperUtils 核心業務操作實作

     編輯:Java 相關知識

核心定位

LdapOperUtils 為靜態工具類(私有建構子),封裝 LDAP 所有高層業務操作,輸入輸出統一使用 Map<String, Object>(單值用 String,多值用 List)、List<Map>(搜尋結果集),呼叫端零 JNDI API 依賴。

內部輔助方法:統一連線取得與關閉

private static DirContext getLdapDirContext(Env env) throws BaseException {
    if (env == null) throw new BaseException("error.common.parameter.empty", new String[]{"env"});
    DirContext ctx = LdapConnectionFactory.getDirContext(env);
    if (ctx == null) throw new BaseException("error.common.dao.ldap.getcontext", null);
    return ctx;
}

private static void closeLdapDirContext(DirContext ctx) throws BaseException {
    if (ctx == null) throw new BaseException("error.common.parameter.empty", new String[]{"dirContext"});
    try { ctx.close(); }
    catch (NamingException ex) {
        log.debug("First close failed, retry...", ex);
        try { ctx.close(); }
        catch (NamingException ex2) {
            throw new BaseException("error.common.dao.ldap.closedircontext", null);
        }
    }
}

Context 結構操作:增、刪、改名

新增子 Context(含屬性)

public static void addContext(DirContext context, String cn, Map attMap)
        throws NamingException, BaseException {
    validateNotNull(context, "context");
    validateNotEmpty(cn, "cn");
    validateNotNull(attMap, "attMap");
    if (attMap.isEmpty()) return;

    Attributes attrs = new BasicAttributes();
    for (Map.Entry entry : attMap.entrySet()) {
        String key = entry.getKey();
        Object valueObj = entry.getValue();
        Attribute att;
        if (valueObj instanceof String) {
            att = new BasicAttribute(key, valueObj); // 單值
        } else if (valueObj instanceof List) {
            att = new BasicAttribute(key);           // 多值
            for (Object v : (List) valueObj) att.add(v);
        } else {
            att = new BasicAttribute(key, valueObj); // 其他(如 byte[] 密碼)
        }
        attrs.put(att);
    }
    context.createSubcontext(cn, attrs);
}

刪除子 Context

public static void deleteContext(DirContext context, String cn)
        throws NamingException, BaseException {
    validateNotNull(context, "context");
    validateNotEmpty(cn, "cn");
    context.destroySubcontext(cn);
}

重命名 Context

public static void reNameContext(DirContext context, String cn, String newCn)
        throws NamingException, BaseException {
    validateNotNull(context, "context");
    validateNotEmpty(cn, "cn");
    validateNotEmpty(newCn, "newCn");
    context.rename(cn, newCn);
}

屬性操作:增、刪、改

新增屬性

public static void addAttributes(DirContext context, String cn, Map attMap)
        throws NamingException, BaseException {
    validateParams(context, cn, attMap);
    Attributes attrs = buildAttributes(attMap);
    context.modifyAttributes(cn, DirContext.ADD_ATTRIBUTE, attrs);
}

刪除屬性(指定屬性名列表)

public static void deleteAttributes(DirContext context, String cn, List attList)
        throws NamingException, BaseException {
    validateParams(context, cn, attList);
    Attributes attrs = new BasicAttributes();
    for (String name : attList) attrs.put(new BasicAttribute(name));
    context.modifyAttributes(cn, DirContext.REMOVE_ATTRIBUTE, attrs);
}

修改屬性(覆蓋模式)

public static void modifyAttributes(DirContext context, String cn, Map attMap)
        throws NamingException, BaseException {
    validateParams(context, cn, attMap);
    Attributes attrs = buildAttributes(attMap);
    context.modifyAttributes(cn, DirContext.REPLACE_ATTRIBUTE, attrs);
}

屬性查詢:靈活的 Map 回傳

取得指定屬性集合

public static Map getAttributes(DirContext context, String cn, List attNameList)
        throws NamingException {
    Map attsMap = new HashMap<>();
    String[] attArray = attNameList.toArray(new String[0]);
    Attributes results = context.getAttributes(cn, attArray);

    for (String name : attNameList) {
        Attribute attr = results.get(name);
        if (attr == null || attr.size() == 0) continue;
        NamingEnumeration vals = attr.getAll();
        if (vals == null) continue;
        Object first = vals.nextElement();
        if (first == null) continue;

        List valList = new ArrayList<>();
        valList.add(first);
        while (vals.hasMoreElements()) valList.add(vals.nextElement());

        attsMap.put(name, valList.size() == 1 ? valList.get(0) : valList);
    }
    return attsMap;
}

取得單一屬性所有值(永遠回傳 List)

public static List getAttributeValues(DirContext context, String cn, String attName)
        throws NamingException {
    List list = new ArrayList<>();
    Map map = getAttributes(context, cn, Collections.singletonList(attName));
    Object val = map.get(attName);
    if (val instanceof List) list.addAll((List) val);
    else if (val != null) list.add(val);
    return list;
}

通用驗證與屬性構建輔助

private static void validateNotNull(Object obj, String paramName) throws BaseException {
    if (obj == null) throw new BaseException("error.common.parameter.empty", new String[]{paramName});
}
private static void validateNotEmpty(String str, String paramName) throws BaseException {
    if (StringUtils.isEmpty(str)) throw new BaseException("error.common.parameter.empty", new String[]{paramName});
}
private static void validateParams(DirContext ctx, String cn, Object param) throws BaseException {
    validateNotNull(ctx, "context");
    validateNotEmpty(cn, "cn");
    validateNotNull(param, param instanceof Map ? "attMap" : "attList");
}

private static Attributes buildAttributes(Map attMap) {
    Attributes attrs = new BasicAttributes();
    for (Map.Entry e : attMap.entrySet()) {
        Attribute att;
        Object v = e.getValue();
        if (v instanceof List) {
            att = new BasicAttribute(e.getKey());
            for (Object o : (List) v) att.add(o);
        } else {
            att = new BasicAttribute(e.getKey(), v);
        }
        attrs.put(att);
    }
    return attrs;
}

設計亮點總結

  • 統一資料結構:Map/List 覆蓋單值/多值,呼叫端無需感知 JNDI Attribute、NamingEnumeration。
  • 防禦性程式設計:參數驗證前置、空集合快速返回、關閉連線重試機制。
  • 例外轉換:底層 NamingException 向上拋出,業務層統一捕獲轉換為 BaseException。
  • 效能優化:attNameList.toArray(new String[0]) 避免手動迴圈複製陣列。

下一篇將介紹進階搜尋功能(單層/子樹、指定回傳屬性)、群組成員維護與認證整合。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved