Java 中文官方教程 2022 版(四十七)(1)

简介: Java 中文官方教程 2022 版(四十七)

命名异常

原文:docs.oracle.com/javase/tutorial/jndi/ops/exception.html

JNDI 包中的许多方法在需要指示无法执行请求的操作时会抛出NamingException。通常,您会看到围绕可能引发NamingException的方法的try/catch包装器

try {
    Context ctx = new InitialContext();
    Object obj = ctx.lookup("somename");
} catch (NamingException e) {
    // Handle the error
    System.err.println(e);
}

异常类层次结构

JNDI 具有丰富的异常层次结构,源自NamingException类。异常的类名是自解释的,并在此处列出。

要特别处理NamingException的特定子类,您需要单独捕获子类。例如,以下代码特别处理AuthenticationException及其子类。

try {
    Context ctx = new InitialContext();
    Object obj = ctx.lookup("somename");
} catch (AuthenticationException e) {
    // attempt to reacquire the authentication information
    ...
} catch (NamingException e) {
    // Handle the error
    System.err.println(e);
}

枚举

操作,如Context.list()DirContext.search()返回一个NamingEnumeration。在这些情况下,如果发生错误并且没有返回结果,则在调用方法时将抛出NamingException或其适当的子类。如果发生错误但有一些结果需要返回,则会返回一个NamingEnumeration,以便您可以获取这些结果。当所有结果耗尽时,调用NamingEnumeration.hasMore()将导致抛出NamingException(或其子类之一)以指示错误。此时,枚举将变为无效状态,不应在其上调用更多方法。

例如,如果执行search()并指定要返回多少个答案的计数限制(n),则search()将返回最多 n 个结果的枚举。如果结果数量超过 n,则当第 n+1 次调用NamingEnumeration.hasMore()时,将抛出SizeLimitExceededException。请参阅本课程的结果计数示例代码。

本教程中的示例

在本教程文本中嵌入的内联示例代码中,通常为了可读性而省略了try/catch子句。通常,因为这里只显示代码片段,所以只包含直接用于说明概念的行。如果查看本教程附带的源文件,您将看到用于NamingExceptiontry/catch子句的适当位置。

javax.naming 包中的异常可以在这里找到。

查找一个对象

原文:docs.oracle.com/javase/tutorial/jndi/ops/lookup.html

要从命名服务中查找对象,请使用Context.lookup()并传递要检索的对象的名称。假设在命名服务中有一个名为cn=Rosanna Lee,ou=People的对象。要检索对象,您可以编写

Object obj = ctx.lookup("cn=Rosanna Lee,ou=People");

lookup()返回的对象类型取决于底层命名系统和对象本身关联的数据。命名系统可以包含许多不同类型的对象,在系统的不同部分查找对象可能会产生不同类型的对象。在这个例子中,"cn=Rosanna Lee,ou=People"恰好绑定到一个上下文对象(javax.naming.ldap.LdapContext)。你可以将lookup()的结果转换为目标类。

例如,以下代码查找对象"cn=Rosanna Lee,ou=People"并将其转换为LdapContext

import javax.naming.ldap.LdapContext;
...
LdapContext ctx = (LdapContext) ctx.lookup("cn=Rosanna Lee,ou=People");

完整的示例在文件Lookup.java中。


Java SE 6 中有两个新的静态方法可用于查找名称:

这些方法提供了一种快捷的查找名称的方式,而无需实例化 InitialContext。

列出上下文

原文:docs.oracle.com/javase/tutorial/jndi/ops/list.html

Context.lookup()一次获取一个对象不同,您可以通过一次操作列出整个上下文。有两种列出上下文的方法:一种返回绑定,另一种仅返回名称到对象类名对。

Context.List()方法

Context.list()返回一个NameClassPair的枚举。每个NameClassPair包含对象的名称和类名。以下代码片段列出了"ou=People"目录的内容(即在"ou=People"目录中找到的文件和目录)。

NamingEnumeration list = ctx.list("ou=People");
while (list.hasMore()) {
    NameClassPair nc = (NameClassPair)list.next();
    System.out.println(nc);
}

运行这个示例会产生以下输出。

# java List
cn=Jon Ruiz: javax.naming.directory.DirContext
cn=Scott Seligman: javax.naming.directory.DirContext
cn=Samuel Clemens: javax.naming.directory.DirContext
cn=Rosanna Lee: javax.naming.directory.DirContext
cn=Maxine Erlund: javax.naming.directory.DirContext
cn=Niels Bohr: javax.naming.directory.DirContext
cn=Uri Geller: javax.naming.directory.DirContext
cn=Colleen Sullivan: javax.naming.directory.DirContext
cn=Vinnie Ryan: javax.naming.directory.DirContext
cn=Rod Serling: javax.naming.directory.DirContext
cn=Jonathan Wood: javax.naming.directory.DirContext
cn=Aravindan Ranganathan: javax.naming.directory.DirContext
cn=Ian Anderson: javax.naming.directory.DirContext
cn=Lao Tzu: javax.naming.directory.DirContext
cn=Don Knuth: javax.naming.directory.DirContext
cn=Roger Waters: javax.naming.directory.DirContext
cn=Ben Dubin: javax.naming.directory.DirContext
cn=Spuds Mackenzie: javax.naming.directory.DirContext
cn=John Fowler: javax.naming.directory.DirContext
cn=Londo Mollari: javax.naming.directory.DirContext
cn=Ted Geisel: javax.naming.directory.DirContext

Context.listBindings()方法

Context.listBindings()返回一个Binding的枚举。BindingNameClassPair的子类。一个绑定不仅包含对象的名称和类名,还包含对象本身。以下代码枚举了"ou=People"上下文,打印出每个绑定的名称和对象。

NamingEnumeration bindings = ctx.listBindings("ou=People");
while (bindings.hasMore()) {
    Binding bd = (Binding)bindings.next();
    System.out.println(bd.getName() + ": " + bd.getObject());
}

运行这个示例会产生以下输出。

# java ListBindings
cn=Jon Ruiz: com.sun.jndi.ldap.LdapCtx@1d4c61c
cn=Scott Seligman: com.sun.jndi.ldap.LdapCtx@1a626f
cn=Samuel Clemens: com.sun.jndi.ldap.LdapCtx@34a1fc
cn=Rosanna Lee: com.sun.jndi.ldap.LdapCtx@176c74b
cn=Maxine Erlund: com.sun.jndi.ldap.LdapCtx@11b9fb1
cn=Niels Bohr: com.sun.jndi.ldap.LdapCtx@913fe2
cn=Uri Geller: com.sun.jndi.ldap.LdapCtx@12558d6
cn=Colleen Sullivan: com.sun.jndi.ldap.LdapCtx@eb7859
cn=Vinnie Ryan: com.sun.jndi.ldap.LdapCtx@12a54f9
cn=Rod Serling: com.sun.jndi.ldap.LdapCtx@30e280
cn=Jonathan Wood: com.sun.jndi.ldap.LdapCtx@16672d6
cn=Aravindan Ranganathan: com.sun.jndi.ldap.LdapCtx@fd54d6
cn=Ian Anderson: com.sun.jndi.ldap.LdapCtx@1415de6
cn=Lao Tzu: com.sun.jndi.ldap.LdapCtx@7bd9f2
cn=Don Knuth: com.sun.jndi.ldap.LdapCtx@121cc40
cn=Roger Waters: com.sun.jndi.ldap.LdapCtx@443226
cn=Ben Dubin: com.sun.jndi.ldap.LdapCtx@1386000
cn=Spuds Mackenzie: com.sun.jndi.ldap.LdapCtx@26d4f1
cn=John Fowler: com.sun.jndi.ldap.LdapCtx@1662dc8
cn=Londo Mollari: com.sun.jndi.ldap.LdapCtx@147c5fc
cn=Ted Geisel: com.sun.jndi.ldap.LdapCtx@3eca90

终止 NamingEnumeration

一个NamingEnumeration可以以自然、显式或意外的方式终止。

无论枚举如何被终止,一旦终止,就不能再使用。在终止的枚举上调用方法会产生未定义的结果。

为什么有两种不同的列出方法?

list()适用于浏览器样式的应用程序,只需显示上下文中对象的名称。例如,浏览器可能会列出上下文中的名称,并等待用户选择其中一个或几个名称以执行进一步操作。这类应用程序通常不需要访问上下文中的所有对象。

listBindings() 适用于需要对上下文中的对象进行批量操作的应用程序。例如,备份应用程序可能需要对文件目录中的所有对象执行“文件统计”操作。或者打印机管理程序可能希望重新启动建筑物中的所有打印机。为了执行这些操作,这些应用程序需要获取上下文中绑定的所有对象。因此,将对象作为枚举的一部分返回更为方便。

应用程序可以使用list()或可能更昂贵的listBindings(),具体取决于它所需的信息类型。

添加、替换或移除绑定

原文:docs.oracle.com/javase/tutorial/jndi/ops/bind.html

Context 接口包含用于在上下文中添加、替换和移除绑定的方法。

添加绑定

Context.bind() 用于向上下文添加绑定。它接受对象的名称和要绑定的对象作为参数。


在继续之前: 本课程中的示例需要您对模式进行添加。您必须在 LDAP 服务器中关闭模式检查,或者将伴随本教程的模式添加到服务器中。这两项任务通常由目录服务器的管理员执行。请参阅 LDAP 设置课程。


// Create the object to be bound
Fruit fruit = new Fruit("orange");
// Perform the bind
ctx.bind("cn=Favorite Fruit", fruit);

这个例子 创建一个 Fruit 类的对象,并将其绑定到上下文 ctx 中的名称 "cn=Favorite Fruit"。如果随后在 ctx 中查找名称 "cn=Favorite Fruit",则会得到 fruit 对象。请注意,要编译 Fruit 类,您需要 FruitFactory 类。

如果您运行此示例两次,则第二次尝试将失败,并显示 NameAlreadyBoundException。这是因为名称 "cn=Favorite Fruit" 已经绑定。要使第二次尝试成功,您必须使用 rebind()

添加或替换绑定

rebind() 用于添加或替换绑定。它接受与 bind() 相同的参数,但语义是如果名称已经绑定,则将解绑并绑定新给定的对象。

// Create the object to be bound
Fruit fruit = new Fruit("lemon");
// Perform the bind
ctx.rebind("cn=Favorite Fruit", fruit);

当你运行这个例子时,它将替换由bind()例子创建的绑定。


移除绑定

要移除绑定,您可以使用unbind()

// Remove the binding
ctx.unbind("cn=Favorite Fruit");

运行时,这个例子将移除由bind()rebind()例子创建的绑定。

重命名

原文:docs.oracle.com/javase/tutorial/jndi/ops/rename.html

您可以使用Context.rename()在上下文中重命名对象。

// Rename to Scott S
ctx.rename("cn=Scott Seligman", "cn=Scott S");


这个例子 将绑定到"cn=Scott Seligman"的对象重命名为"cn=Scott S"。在验证对象已重命名后,程序将其重新命名为原始名称("cn=Scott Seligman")。

// Rename back to Scott Seligman
ctx.rename("cn=Scott S", "cn=Scott Seligman");

欲了解更多关于 LDAP 条目重命名的示例,请查看 LDAP 用户的高级主题课程。

创建和销毁子上下文

原文:docs.oracle.com/javase/tutorial/jndi/ops/create.html

Context接口包含用于创建和销毁 子上下文 的方法,即绑定在同一类型的另一个上下文中的上下文。

此处描述的示例使用具有属性的对象,并在目录中创建一个子上下文。您可以使用这些DirContext方法在将绑定或子上下文添加到命名空间时将属性与对象关联起来。例如,您可以创建一个Person对象并将其绑定到命名空间,并同时关联有关该Person对象的属性。命名等效项将没有属性。

createSubcontext()与 bind()的不同之处在于它创建一个新对象,即一个新的上下文,将其绑定到目录,而 bind()将给定对象绑定到目录。

创建上下文

要创建命名上下文,您需要向createSubcontext() 提供要创建的上下文的名称。要创建具有属性的上下文,您需要向DirContext.createSubcontext() 提供要创建的上下文的名称和其属性。


在继续之前: 本课程中的示例需要您对模式进行添加。您必须在 LDAP 服务器中关闭模式检查,或者将伴随本教程的模式添加到服务器中。这两项任务通常由目录服务器的管理员执行。请参阅 LDAP 设置课程。


// Create attributes to be associated with the new context
Attributes attrs = new BasicAttributes(true); // case-ignore
Attribute objclass = new BasicAttribute("objectclass");
objclass.add("top");
objclass.add("organizationalUnit");
attrs.put(objclass);
// Create the context
Context result = ctx.createSubcontext("NewOu", attrs);

This example 创建了一个名为"ou=NewOu"的新上下文,在上下文ctx中有一个属性"objectclass",其值为"top""organizationalUnit"

# java Create
ou=Groups: javax.naming.directory.DirContext
ou=People: javax.naming.directory.DirContext
ou=NewOu: javax.naming.directory.DirContext

This example 创建了一个名为"NewOu"的新上下文,它是ctx的子上下文。


销毁上下文

要销毁一个上下文,您需要向destroySubcontext() 提供要销毁的上下文的名称。

// Destroy the context
ctx.destroySubcontext("NewOu");

This example 在上下文ctx中销毁了上下文"NewOu"

属性名称

原文:docs.oracle.com/javase/tutorial/jndi/ops/attrnames.html

一个属性由一个属性标识符和一组属性值组成。属性标识符,也称为属性名称,是一个字符串,用于标识属性。属性值是属性的内容,其类型不限于字符串。当您想要为检索、搜索或修改指定特定属性时,您使用属性名称。名称也会被返回操作返回的属性(例如在目录中执行读取或搜索时)。

在使用属性名称时,您需要了解某些目录服务器功能,以免对结果感到惊讶。这些功能在下一小节中描述。

属性类型

在 LDAP 等目录中,属性的名称标识属性的类型,通常称为属性类型名称。例如,属性名称"cn"也称为属性类型名称。属性的类型定义指定属性值应具有的语法,它是否可以具有多个值,以及在执行比较和排序操作时使用的相等性和排序规则。

属性子类化

一些目录实现支持属性子类化,其中服务器允许以其他属性类型定义属性类型。例如,"name"属性可能是所有与名称相关属性的超类:"commonName"可能是"name"的子类。对于支持此功能的目录实现,请求"name"属性可能返回"commonName"属性。

当访问支持属性子类化的目录时,您必须注意服务器可能返回具有与您请求的名称不同的属性。为了最大程度减少这种情况发生的机会,请使用最派生的子类。

属性名称同义词

一些目录实现支持属性名称的同义词。例如,"cn"可能是"commonName"的同义词。因此,对"cn"属性的请求可能返回"commonName"属性。

当访问支持属性名称同义词的目录时,您必须注意服务器可能返回具有与您请求的名称不同的属性。为了防止这种情况发生,请使用规范属性名称而不是其同义词。规范属性名称是属性定义中使用的名称;同义词是在其定义中指向规范属性名称的名称。

语言偏好

LDAP v3 的扩展(RFC 2596)允许您在属性名称旁指定语言代码。这类似于属性子类化,一个属性名称可以表示多个不同的属性。例如,一个具有两种语言变体的"description"属性:

description: software
description;lang-en: software products
description;lang-de: Softwareprodukte

请求"description"属性将返回所有三个属性。

当访问支持此功能的目录时,您必须注意服务器可能返回与您请求的名称不同的属性。

读取属性

原文:docs.oracle.com/javase/tutorial/jndi/ops/getattrs.html

要从目录中读取对象的属性,请使用DirContext.getAttributes()并传递您想要属性的对象的名称。假设命名服务中的一个对象的名称为"cn=Ted Geisel, ou=People"。要检索此对象的属性,您需要类似于以下的code

Attributes answer = ctx.getAttributes("cn=Ted Geisel, ou=People");

您可以按照以下方式打印此答案的内容。

for (NamingEnumeration ae = answer.getAll(); ae.hasMore();) {
    Attribute attr = (Attribute)ae.next();
    System.out.println("attribute: " + attr.getID());
    /* Print each value */
    for (NamingEnumeration e = attr.getAll(); e.hasMore();
         System.out.println("value: " + e.next()))
        ;
}

这将产生以下输出。

# java GetattrsAll
attribute: sn
value: Geisel
attribute: objectclass
value: top
value: person
value: organizationalPerson
value: inetOrgPerson
attribute: jpegphoto
value: [B@1dacd78b
attribute: mail
value: Ted.Geisel@JNDITutorial.example.com
attribute: facsimiletelephonenumber
value: +1 408 555 2329
attribute: telephonenumber
value: +1 408 555 5252
attribute: cn
value: Ted Geisel

返回选定的属性

要读取属性的选择性子集,您需要提供一个字符串数组,这些字符串是您想要检索的属性的属性标识符。

// Specify the ids of the attributes to return
String[] attrIDs = {"sn", "telephonenumber", "golfhandicap", "mail"};
// Get the attributes requested
Attributes answer = ctx.getAttributes("cn=Ted Geisel, ou=People", attrIDs);

此示例请求对象"cn=Ted Geisel, ou=People""sn""telephonenumber""golfhandicap""mail"属性。此对象除了"golfhandicap"属性外,其余属性都存在,因此答案中返回了三个属性。以下是示例的输出。

# java Getattrs
attribute: sn
value: Geisel
attribute: mail
value: Ted.Geisel@JNDITutorial.example.com
attribute: telephonenumber
value: +1 408 555 5252

修改属性

原文:docs.oracle.com/javase/tutorial/jndi/ops/modattrs.html

DirContext 接口包含了修改目录中对象的属性和属性值的方法。

Java 中文官方教程 2022 版(四十七)(2)https://developer.aliyun.com/article/1488495

相关文章
|
21小时前
|
Web App开发 JavaScript 前端开发
《手把手教你》系列技巧篇(三十九)-java+ selenium自动化测试-JavaScript的调用执行-上篇(详解教程)
【5月更文挑战第3天】本文介绍了如何在Web自动化测试中使用JavaScript执行器(JavascriptExecutor)来完成Selenium API无法处理的任务。首先,需要将WebDriver转换为JavascriptExecutor对象,然后通过executeScript方法执行JavaScript代码。示例用法包括设置JS代码字符串并调用executeScript。文章提供了两个实战场景:一是当时间插件限制输入时,用JS去除元素的readonly属性;二是处理需滚动才能显示的元素,利用JS滚动页面。还给出了一个滚动到底部的代码示例,并提供了详细步骤和解释。
19 10
|
1天前
|
JavaScript 前端开发 测试技术
《手把手教你》系列技巧篇(三十八)-java+ selenium自动化测试-日历时间控件-下篇(详解教程)
【5月更文挑战第2天】在自动化测试过程中,经常会遇到处理日期控件的点击问题。宏哥之前分享过一种方法,但如果输入框是`readonly`属性,这种方法就无法奏效了。不过,通过修改元素属性,依然可以实现自动化填写日期。首先,定位到日期输入框并移除`readonly`属性,然后使用`sendKeys`方法输入日期。这样,即使输入框设置了`readonly`,也能成功处理日期控件。
14 1
|
2天前
|
Java 测试技术 Python
《手把手教你》系列技巧篇(三十七)-java+ selenium自动化测试-日历时间控件-上篇(详解教程)
【5月更文挑战第1天】该文介绍了使用Selenium自动化测试网页日历控件的方法。首先,文章提到在某些Web应用中,日历控件常用于选择日期并筛选数据。接着,它提供了两个实现思路:一是将日历视为文本输入框,直接输入日期;二是模拟用户交互,逐步选择日期。文中给出了JQueryUI网站的一个示例,并展示了对应的Java代码实现,包括点击日历、选择日期等操作。
13 0
|
8天前
|
Java 测试技术 Python
《手把手教你》系列技巧篇(三十六)-java+ selenium自动化测试-单选和多选按钮操作-番外篇(详解教程)
【4月更文挑战第28天】本文简要介绍了自动化测试的实战应用,通过一个在线问卷调查(<https://www.sojump.com/m/2792226.aspx/>)为例,展示了如何遍历并点击问卷中的选项。测试思路包括找到单选和多选按钮的共性以定位元素,然后使用for循环进行点击操作。代码设计方面,提供了Java+Selenium的示例代码,通过WebDriver实现自动答题。运行代码后,可以看到控制台输出和浏览器的相应动作。文章最后做了简单的小结,强调了本次实践是对之前单选多选操作的巩固。
23 0
|
8天前
|
Java 测试技术 项目管理
Java基础教程(22)-构建工具Maven的基本使用
【4月更文挑战第22天】Maven是Java项目管理及构建工具,简化构建、测试、打包和部署等任务。遵循约定优于配置原则,核心是`pom.xml`配置文件,用于管理依赖和项目信息。安装涉及下载、解压、配置环境变量。在IDEA中使用Maven创建项目,通过`pom.xml`添加依赖和管理版本。常用命令包括`clean`、`compile`、`test`、`package`、`install`和`deploy`。IDEA支持直接执行这些命令。
|
8天前
|
NoSQL Java 关系型数据库
Java基础教程(21)-Java连接MongoDB
【4月更文挑战第21天】MongoDB是开源的NoSQL数据库,强调高性能和灵活性。Java应用通过MongoDB Java驱动与之交互,涉及MongoClient、MongoDatabase、MongoCollection和Document等组件。连接MongoDB的步骤包括:配置连接字符串、创建MongoClient、选择数据库和集合。伪代码示例展示了如何建立连接、插入和查询数据。
|
9天前
|
存储 前端开发 测试技术
《手把手教你》系列技巧篇(三十五)-java+ selenium自动化测试-单选和多选按钮操作-下篇(详解教程)
【4月更文挑战第27天】本文介绍了使用Java+Selenium进行Web自动化测试时,如何遍历和操作多选按钮的方法。文章分为两个部分,首先是一个本地HTML页面的示例,展示了多选按钮的HTML代码和页面效果,并详细解释了遍历多选按钮的思路:找到所有多选按钮的共同点,通过定位这些元素并放入list容器中,然后使用for循环遍历并操作。 第二部分介绍了在JQueryUI网站上的实战,给出了被测网址,展示了代码设计,同样使用了findElements()方法获取所有多选按钮并存储到list中,然后遍历并进行点击操作。最后,文章对整个过程进行了小结,并推荐了作者的其他自动化测试教程资源。
19 0
|
9天前
|
Java 关系型数据库 MySQL
Java基础教程(20)-Java连接mysql数据库CURD
【4月更文挑战第19天】MySQL是流行的关系型数据库管理系统,支持SQL语法。在IDEA中加载jar包到项目类路径:右击项目,选择“Open Module Settings”,添加库文件。使用JDBC连接MySQL,首先下载JDBC驱动,然后通过`Class.forName()`加载驱动,`DriverManager.getConnection()`建立连接。执行CRUD操作,例如创建表、插入数据和查询,使用`Statement`或`PreparedStatement`,并确保正确关闭数据库资源。
|
10天前
|
设计模式 算法 Java
Java基础教程(19)-设计模式简述
【4月更文挑战第19天】设计模式是软件设计中反复使用的代码设计经验,旨在提升代码的可重用性、可扩展性和可维护性。23种模式分为创建型、结构型和行为型三类。创建型模式如工厂方法、抽象工厂、建造者、原型和单例,关注对象创建与使用的分离。结构型模式涉及对象组合,如适配器、装饰器、外观等,增强结构灵活性。行为型模式专注于对象间职责分配和算法合作,包括责任链、命令、观察者等。设计模式提供标准化解决方案,促进代码交流和复用。
|
11天前
|
前端开发 测试技术 Python
《手把手教你》系列技巧篇(三十三)-java+ selenium自动化测试-单选和多选按钮操作-上篇(详解教程)
【4月更文挑战第25天】本文介绍了自动化测试中如何处理单选和多选按钮的操作,包括它们的定义、HTML代码示例以及如何判断和操作这些元素。文章通过一个简单的HTML页面展示了单选和多选框的示例,并提供了Java+Selenium实现的代码示例,演示了如何检查单选框是否选中以及如何进行全选操作。
17 0