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

封裝 JNDI 操作 LDAP 服務的工具類(四之一):屬性修改、查詢與搜尋核心實作

     編輯:Java 相關知識

屬性修改:REPLACE_ATTRIBUTE 模式

public static void modifyAttributes(DirContext context, String cn, Map attMap)
        throws NamingException, BaseException {
    validateParams(context, cn, attMap);
    if (attMap.isEmpty()) return;

    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);
    }
    context.modifyAttributes(cn, DirContext.REPLACE_ATTRIBUTE, attrs);
}

差異於 ADD_ATTRIBUTE(不存在則新增、存在則報錯)與 REMOVE_ATTRIBUTE,REPLACE_ATTRIBUTE 語意為「整體覆蓋」,不存在則建立,存在則完全取代,適合「設定最終狀態」場景。

屬性查詢:高效能 Map 回傳

取得指定屬性列表

public static Map getAttributes(DirContext context, String cn, List attNameList)
        throws NamingException {
    Map attsMap = new HashMap<>();
    if (attNameList == null || attNameList.isEmpty()) {
        // 未指定屬性名單:取回所有屬性(慎用,效能差)
        Attributes results = context.getAttributes(cn);
        // 迭代處理...
    } else {
        // 高效能:單次 RPC 取回指定屬性
        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;
}

角色專用:取得單值字串屬性

public static String getRoleAttributeValues(DirContext context, String cn, String attName)
        throws NamingException {
    List list = getAttributeValues(context, cn, attName);
    return list.isEmpty() ? "" : list.get(0);
}

搜尋核心:統一結果轉換邏輯

單層搜尋(所有屬性)

public static List> searchContextOne(DirContext context, String cn, String filter)
        throws NamingException {
    return searchInternal(context, cn, filter, SearchControls.ONELEVEL_SCOPE, null);
}

子樹搜尋(所有屬性)

public static List> searchContextSub(DirContext context, String cn, String filter)
        throws NamingException {
    return searchInternal(context, cn, filter, SearchControls.SUBTREE_SCOPE, null);
}

內部統一實作(模板方法模式)

private static List> searchInternal(DirContext context, String cn,
        String filter, int scope, String[] returnedAtts) throws NamingException {

    List> resultList = new ArrayList<>();
    SearchControls ctls = new SearchControls();
    ctls.setSearchScope(scope);
    if (returnedAtts != null) ctls.setReturningAttributes(returnedAtts);

    NamingEnumeration results = context.search(cn, filter, ctls);
    while (results != null && results.hasMore()) {
        SearchResult sr = (SearchResult) results.next();
        Attributes attrs = sr.getAttributes();
        if (attrs == null) continue;

        Map row = new HashMap<>();
        for (NamingEnumeration ae = attrs.getAll(); ae.hasMoreElements(); ) {
            Attribute attr = (Attribute) ae.next();
            String attrId = attr.getID();
            NamingEnumeration vals = attr.getAll();
            if (vals == null) continue;

            List valList = new ArrayList<>();
            while (vals.hasMoreElements()) {
                Object v = vals.nextElement();
                if (v != null) valList.add(v);
            }
            row.put(attrId, valList.size() == 1 ? valList.get(0) : valList);
        }
        resultList.add(row);
    }
    return resultList;
}

關鍵重構收益

  • 消除重複代碼:三種搜尋公開方法委派同一私有實作,僅參數不同。
  • 靈活擴充:新增 OBJECT_SCOPE、分頁、排序等需求只需修改內部方法。
  • 效能預設值:公開方法預設不限制回傳屬性(相容舊代碼),新代碼建議顯式呼叫帶 returnedAtts 版本。

下一篇將示範完整整合測試:建立 Active Directory 使用者、設定密碼與帳號啟用屬性。

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