# 存储和读取对象

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

应用程序和服务可以以不同的方式使用目录来存储和定位对象：

*   存储（副本）对象本身。
*   存储对象的引用。
*   存储描述对象的属性。

一般而言，Java 对象的序列化表单包含对象的状态和对象的引用，其中包含可用于联系对象的寻址信息的紧凑表示。 [查找对象](../ops/lookup.html)课程中给出了一些示例。对象的属性是用于描述对象的属性;属性可能包括寻址和/或状态信息。

这三种使用方法中的哪一种取决于正在构建的应用程序/系统以及它如何与将共享存储在目录中的对象的其他应用程序和系统进行互操作。另一个因素是服务提供商和底层目录服务提供的支持。

以编程方式，所有应用程序在目录中存储对象时使用以下方法之一：

*   [`Context.bind（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#bind-javax.naming.Name-java.lang.Object-)
*   [`DirContext.bind（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#bind-javax.naming.Name-java.lang.Object-javax.naming.directory.Attributes-)
*   [`Context.rebind（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#rebind-javax.naming.Name-java.lang.Object-)
*   [`DirContext.rebind（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#rebind-javax.naming.Name-java.lang.Object-javax.naming.directory.Attributes-)

应用程序将要存储的对象传递给其中一个方法。然后，根据服务提供者支持的对象类型，该对象将转换为底层目录服务可接受的表示。

本课程介绍了如何在存储对象后将可序列化对象存储在目录中，您只需使用 [`lookup（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#lookup-javax.naming.Name-) 从目录中获取对象的副本，无论是实际存储了什么类型的信息。

您不仅可以通过使用 `lookup（）`来获取对象，还可以在 [`列出`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#list-javax.naming.Name-) 上下文时以及 [`搜索时`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#search-javax.naming.Name-) 一个上下文或其子树。在所有这些情况下，可能涉及 _ 对象工厂 _。对象工厂在 [JNDI 教程](https://docs.oracle.com/javase/jndi/tutorial/objects/factory/index.html)中有详细讨论。

要存储下面的对象类型，请参阅 JNDI 教程：

*   [可引用对象和 JNDI `参考` s](https://docs.oracle.com/javase/jndi/tutorial/objects/storing/reference.html)
    [中的 bind（）示例添加，替换或删除绑定](../ops/bind.html)课程使用可引用对象。
*   [具有属性的对象（ `DirContext` ）](https://docs.oracle.com/javase/jndi/tutorial/objects/storing/dircontext.html)
*   [RMI（Java 远程方法调用）对象（包括那些使用 IIOP 的对象）](https://docs.oracle.com/javase/jndi/tutorial/objects/storing/remote.html)
*   [CORBA 对象](https://docs.oracle.com/javase/jndi/tutorial/objects/storing/corba.html)

* * *

**继续之前：**要成功运行这些示例，您必须关闭服务器中的模式检查，或者将本教程附带的 [`the Java schema`](../software/config/java.schema) 添加到服务器。此任务通常由目录服务器的管理员执行。有关详细信息，请参阅[软件设置](../software/content.html#SCHEMA)课程。

**Windows Active Directory：** [`Context.rebind（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#rebind-javax.naming.Name-java.lang.Object-) 和 [`DirContext.rebind（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#rebind-javax.naming.Name-java.lang.Object-javax.naming.directory.Attributes-) 对 Active 不起作用目录，因为这些方法通过读取要更新的条目的属性，删除条目，然后添加包含已修改属性的新条目来工作。 Active Directory 返回一些用户无法设置的属性，导致最终添加步骤失败。此问题的解决方法是使用 [`DirContext.getAttributes（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#getAttributes-javax.naming.Name-) 来获取并保存要保留的属性。然后，删除该条目并使用 [`DirContext.bind（）`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#bind-javax.naming.Name-java.lang.Object-javax.naming.directory.Attributes-) 将其添加回保存的属性（以及您要添加的任何其他属性）。