# 操纵 LdapName（专有名称）

> 原文： [https://docs.oracle.com/javase/tutorial/jndi/newstuff/ldapname.html](https://docs.oracle.com/javase/tutorial/jndi/newstuff/ldapname.html)

LDAP 的字符串表示使用专有名称（DN）。用于表示 DN 的字符串格式在 [RFC 2253](http://www.ietf.org/rfc/rfc2253.txt) 中指定。 DN 由称为相对专有名称（RDN）的组件组成。以下是 DN 的示例：

“CN = John Smith，O = Isode Limited，C = GB”

它由以下 RDN 组成：

*   CN =约翰史密斯
*   O = Isode Limited
*   C = GB

下面的类分别代表 DN 和 RDN。

*   [`javax.naming.ldap.LdapName`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html)
*   [`javax.naming.ldap.Rdn`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/Rdn.html)

LdapName 类实现 [`javax.naming.Name`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Name.html)接口类似于 [`javax.naming.CompoundName`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Name.html)和 [`javax.naming.CompositeName`](https://docs.oracle.com/javase/8/docs/api/javax/naming/CompositeName.html)类。

LdapName 和 Rdn 类允许轻松操作 DN 和 RDN。使用这些 API，可以通过配对名称和值来轻松构建 RDN。可以使用 RDN 列表构建 DN。类似地，DN 和 RDN 的各个组件可以从它们的字符串表示中检索。

## LdapName

可以使用 [RFC 2253](http://www.ietf.org/rfc/rfc2253.txt) 中定义的字符串表示或使用 Rdns 列表创建 LdapName。使用前一种方式时，将根据 RFC2253 中定义的规则解析指定的字符串。如果字符串不是有效的 DN，则抛出 [`InvalidNameException`](https://docs.oracle.com/javase/8/docs/api/javax/naming/InvalidNameException.html)。这是一个使用构造函数来解析 LDAP 名称并打印其组件的示例。

```
String name = "cn=Mango,ou=Fruits,o=Food";
try {
    LdapName dn = new LdapName(name);
    System.out.println(dn + " has " + dn.size() + " RDNs: ");
    for (int i = 0; i < dn.size(); i++) {
        System.out.println(dn.get(i));
    }
} catch (InvalidNameException e) {
    System.out.println("Cannot parse name: " + name);
}

```

使用`“cn = Mango，ou = Fruits，o = Food”`的输入运行此示例会产生以下结果：

```
cn=Mango,ou=Fruits,o=Food has 3 RDNs: 
o=Food
ou=Fruits
cn=Mango

```

LdapName 类包含以 RDN 和字符串形式访问其组件，修改 LdapName，比较两个 LdapNames 是否相等以及获取名称的字符串表示形式的方法。

### 访问 LDAP 名称的名称组件：

以下是可用于将名称组件作为 RDN 和字符串进行访问的方法：

[`getRdn（int posn）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#getRdn-int-)
[`得到（int posn）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#get-int-)
[`getRdns（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#getRdns--)
[`getAll（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#getAll--)
[`getPrefix（int posn）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#getPrefix-intposn-)
[`getSuffix（int posn）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#getSuffix-intposn-)
[`克隆（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#clone--)

要在 LdapName 中的特定位置检索组件，请使用 getRdn（）或 get（）。前面的构造函数示例显示了它的使用示例。 [`getRdns（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#getRdns--) 返回所有 RDN 的列表， [`getAll（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#getAll--) 返回 LdapName 的所有组件作为枚举。

最右边的 RDN 位于索引 0，最左边的 RDN 位于索引 n-1。例如，可分辨名称：`“cn =芒果，ou =水果，o =食物”`按以下顺序编号，范围从 0 到 2： `{o =食物，ou =水果， cn =芒果}`

您还可以将 LdapNames 的后缀或前缀作为 LdapName 实例获取。这是一个 [`example`](examples/LdapNameSuffixPrefix.java) ，它获取 LDAP 名称的后缀和前缀。

```
LdapName dn = new LdapName("cn=Mango, ou=Fruits, o=Food");
Name suffix = dn.getSuffix(1);  // 1 <= index < cn.size()
Name prefix = dn.getPrefix(1);  // 0 <= index < 1

```

运行此程序时，它会生成以下输出：

```
cn=Mango ou=Fruits
o=Food 

```

要制作 LdapName 的副本，请使用 clone（）。

### 修改 LDAP 名称

以下是可用于修改 LDAP 名称的方法：

[`add（Rdn rdn）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#add-Rdn-)
[`add（String comp）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#add-String-)
[`add（int posn ，String comp）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#add-int-String-)
[`addAll（List suffixRdns）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#addAll-List-)
[`addAll（名称后缀）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#addAll-Namesuffix-)
[`addAll（int posn，List suffixRdns）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#addAll-int-List-)
[`addAll（int posn，Name suffix）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#addAll-int-Name-)
[`删除（int posn）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#remove-int-)

创建 LdapName 实例后，您可以添加和删除组件。这是一个 [`example`](examples/ModifyLdapName.java) ，它将 LdapName 附加到现有的 LdapName，向前端和末尾添加组件，并删除第二个组件。

```
     LdapName dn = new LdapName("ou=Fruits,o=Food");
     LdapName dn2 = new LdapName("ou=Summer");
     System.out.println(dn.addAll(dn2)); // ou=Summer,ou=Fruits,o=Food
     System.out.println(dn.add(0, "o=Resources")); 
// ou=Summer,ou=Fruits,o=Food,o=Resources
     System.out.println(dn.add("cn=WaterMelon")); 
// cn=WaterMelon,ou=Summer,ou=Fruits,o=Food,o=Resources
     System.out.println(dn.remove(1));  // o=Food
     System.out.println(dn);  
// cn=WaterMelon,ou=Summer,ou=Fruits,o=Resources

```

### 比较 LDAP 名称

以下是可用于比较两个 LDAP 名称的方法：

[`compareTo（对象名称）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#compareTo-Object-)
[`等于（对象名称）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#equals-Object-)
[`endsWith（List）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#endsWith-List-)
[`endWith（名称）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#endsWith-Name-)
[`起始（列表 rdns）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#startsWith-iList-)
[`startsWith（名称）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#startsWith-Name-)
[`isEmpty（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#isEmpty--)

您可以使用 `compareTo（）`对 LdapName 实例列表进行排序。 `equals（）`方法可以让您确定两个 LdapNames 在语法上是否相等。如果两个 LdapNames 在相同的顺序中具有相同（大小写完全匹配）的组件，则它们是相等的。

使用 `startsWith（）`和 `endsWith（）`，您可以了解 LdapName 是以另一个 LdapName 开头还是结尾;也就是说，LdapName 是否是另一个 LdapName 的后缀或前缀。

方便方法 `isEmpty（）`使您可以确定 LdapName 是否具有零组件。您也可以使用表达式 `size（）== 0` 来执行相同的检查。

这是一个例子， [`CompareLdapNames`](examples/CompareLdapNames.java) ，它使用了一些这些比较方法。

```
LdapName one = new LdapName("cn=Vincent Ryan, ou=People, o=JNDITutorial");
LdapName two = new LdapName("cn=Vincent Ryan");
LdapName three = new LdapName("o=JNDITutorial");
LdapName four = new LdapName("");

System.out.println(one.equals(two));        // false
System.out.println(one.startsWith(three));  // true
System.out.println(one.endsWith(two));      // true
System.out.println(one.startsWith(four));   // true
System.out.println(one.endsWith(four));     // true
System.out.println(one.endsWith(three));    // false
System.out.println(one.isEmpty());          // false
System.out.println(four.isEmpty());         // true
System.out.println(four.size() == 0);       // true

```

### 获取字符串表示

下面的方法将为您提供根据 RFC 2253 中指定的语法格式化的 LDAP 名称的字符串表示形式：

[`toString（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#toString--)

使用 LdapName 构造函数时，提供 LDAP 名称的字符串表示形式并返回 LdapName 实例。要执行相反的操作，即获取 LdapName 实例的字符串表示形式，请使用 `toString（）`。 `toString（）`的结果可以反馈给构造函数，以生成一个等于原始 LdapName 实例的 LdapName 实例。这是一个例子， [`LdapNametoString`](examples/LdapNametoString.java) ：

```
LdapName dn = new LdapName(name);
String str = dn.toString();
System.out.println(str);
LdapName dn2 = new LdapName(str);
System.out.println(dn.equals(dn2));  // true

```

### LdapName 作为 Context 方法的参数

Context 方法要求将复合名称或复合名称作为参数传递给其方法。因此，LdapName 可以直接传递给上下文方法，如 [`LookupLdapName`](examples/LookupLdapName.java) 所示：

```
// Create the initial context
Context ctx = new InitialContext(env);

// An LDAP name
LdapName dn = new LdapName("ou=People,o=JNDITutorial");

// Perform the lookup using the dn
Object obj = ctx.lookup(dn);

```

类似地，当 Context 方法从 list（），listBindings（）或 search（）操作返回结果时，可以通过调用 [`getNameInNamespace（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/LdapName.html#getNameInNamepspace--) 来检索 DN。 LdapName 可以直接从 DN 构造，如示例 [`RetrievingLdapName`](examples/RetrievingLdapName.java) 所示：

```
while (answer.hasMore()) {
    SearchResult sr = (SearchResult) answer.next();
    String name = sr.getNameInNamespace();
    System.out.println(name);
    LdapName dn = new LdapName(name);

    // do something with the dn

```