JNDIの一般的な理解:
JNDI(Javaネーミングとディレクトリインターフェイス)命名およびディレクトリサービスを使用する一連のインターフェイスを提供します。ユーザーは、それを介してネーミングおよびディレクトリサービスを使用できます。 JDBCのように。 JNDIには、名前付きサービスとディレクトリサービスの2つの部分が含まれています。ディレクトリサービスには、いくつかの属性オブジェクトが含まれるディレクトリオブジェクトディレクトリオブジェクトが含まれています。プロパティに関する多くの操作を提供します。
命名およびディレクトリサービス:
オペレーティングシステムのファイルシステムなどのネーミングおよびディレクトリサービスを使用しており、ファイルの操作、クエリ、追加、削除などの機能を提供します。 DNSサービスは、URLとIPアドレスを結合します。ネーミングおよびディレクトリシステムの最も重要な機能は、名前とオブジェクトをバインドすることです。それに基づいて、ルックアップや検索などのより多くの機能も提供します。さらに、保存されたオブジェクトには特定の階層があります。このようなサービスを使用すると、オブジェクトをより効果的に管理および操作できます。
ネーミングサービスは、名前をオブジェクトにマッピングします。 RMIレジストリとCorbaネーミングサービスはどちらも命名サービスです。
ディレクトリサービスはオブジェクトも保存しますが、ディレクトリサービスはこれらのオブジェクトの関連するプロパティを認識します。プロジェクトプロパティを使用して、ディレクトリを検索できます。
1990年代初頭、Lightweight Directory Access Protocol(LightDiretoryAccessProtocol)が標準ディレクトリプロトコルとして開発され、JNDIはLDAPにアクセスできました。
J2SEはJNDIに5つの拡張パッケージを提供します:
コンテキスト:コンテキストは、階層またはディレクトリとして理解できる名前からオブジェクトまでのバインディングのセットです。また、SubContextの次のレイヤーを含めることもできます。ネーミングおよびディレクトリサービスを使用するときに初期コンテキストを取得することは、名前空間操作全体へのエントリです。ディレクトリサービスにはdircontextがあります。
JNDI(Javaネーミングおよびディレクトリインターフェイス)は、さまざまな名前付き指名およびディレクトリサービスを見つけてアクセスするための共通で統一されたインターフェイスを開発者に提供するアプリケーション設計のAPIです。 JDBCは、抽象化層の上に構築されています。
JNDIがアクセスできる既存のディレクトリとサービスは次のとおりです。
DNS、XNAM、Novell Directory Service、LDAP(LightWeight Directory Access Protocol)、Corba Object Service、File System、Windows XP/2000/NT/ME/9Xレジストリ、RMI、DSML V1&V2、NIS。
JNDIの利点:
一般的なインターフェイスを使用してさまざまな種類のサービスにアクセスするために、多数の命名およびディレクトリサービスが含まれています。複数の命名またはディレクトリサービスに同時に接続できます。論理的な関連性を確立し、オブジェクトやリソースの物理IDをガイドすることなく、名前をJavaオブジェクトまたはリソースに関連付けることができます。
JNDIパッケージ:
JNDI対JDBC:
JNDIは、ネットワーク上でサービスを見つけてアクセスするための統一された方法を提供します。データベースまたはネーミングサービスのレコードに対応するリソース名を指定することにより、データベース接続の確立に必要な情報を返します。
コード例:
try {context cntxt = new initialContext(); dataSource ds =(dataSource)cntxt.lookup( "jdbc/dpt");} catch(namingexception ne){...} JNDIとJMS:
メッセージ通信は、ソフトウェアコンポーネントまたはアプリケーションが通信するために使用する方法です。 JMSは、アプリケーションがメッセージを作成、送信、受信、および読み取りできるJavaテクノロジーです。
コード例:
try {properties env = new Properties(); initialContext inictxt = new initialContext(env); topicConnectionFactory connfactory =(topicConnectionFactory)Inictup( "ttopicConnectionFactory"); ...} catch(namingexception ne){...}}特定のディレクトリにアクセスしてください。たとえば、人はオブジェクトであり、その人の名前、電話番号、メールアドレス、郵便番号、その他の属性など、いくつかの属性があります。 getattributes()メソッドによる
属性属性= directory.getattributes(personname).get( "email"); string email =(string)attr.get();
JNDIを使用することにより、顧客にオブジェクトの名前または属性を使用してオブジェクトを見つけさせます。
foxes = directory.search( "o = wiz、c = us"、 "sn = fox"、controls);
JNDIを使用してプリンターを使用してプリンターやデータベースなどのオブジェクトを見つけることによるプリンターを見つける例:
プリンタープリンター=(プリンター)namespace.lookup(printername); printer.print(document);
名前空間を閲覧する:
namingEnumeration list = namespace.list( "o = widget、c = us"); while(list.hasmore()){nameclasspair entry =(nameclasspair)list.next(); display(entry.getName()、entry.getClassName();}コードの例:名前、クラス名、およびバインドされたオブジェクトを再びゲットします。
namingEnumeration namenumlist = ctxt.listbinding( "cntxtname"); ... (SomeObject)bnd.getObject();}
名前サービスとディレクトリサービスの概念を理解することは、JNDIをより適切に使用するのに役立ちます。命名サービス名サービスは、名前をオブジェクトに関連付ける方法と、名前を介してオブジェクトを見つける方法を定義します。典型的な例は次のとおりです。DNSはドメイン名をIPと関連付け、ファイルシステムはファイル名をファイルに関連付けます。名前サービスでは、主な概念:
- 名前(名前)、ファイル名、ドメイン名など、名前システム内の実際のオブジェクトのコード名は、関連するオブジェクトを見つけるために使用されます。システムは、ファイルシステムが「/」を使用して階層を表すなど、異なるネーミング仕様を備えていますが、DNSは「」を使用します。
- バインディング、名前と実際のオブジェクトの関連付け。
- 参照とアドレス。オブジェクトを名前システムに直接保存できない場合、参照を使用して、基準を介して実際のオブジェクトを見つける必要があります。システムでは、保存された参照のコンテンツはアドレスと呼ばれます。引用には別の用途があります。名前システムでは、リレーショナルデータベースの外部キーの概念が不足しています。参照を使用することにより、外国の鍵の代替として使用できます。
- コンテキストでは、それは名前オブジェクトコレクションであり、検索、バインディング、拘束力などの名前システムと対話するためのメイン操作を提供します。子のコンテキスト(サブコンテキスト)の関係は、ファイルシステム内のディレクトリとサブディレクトリの関係に似ています。子のコンテキストはコンテキストに含まれており、親コンテキストの名前を通して子のコンテキストに関連付けられています。
- ネーミングシステムと名前空間。名前システムは、同じタイプのコンテキストのコレクションであり、名前サービスを提供します。名前スペースは、ファイルシステムのファイル名やディレクトリなど、名前システム内の名前のコレクションです。
ディレクトリサービスディレクトリサービスは、名前サービスの延長です。名前とオブジェクトを関連付けることに加えて、オブジェクトに属性を含めることもできます。ディレクトリシステムは通常、階層内のデータを整理します。ディレクトリサービスの主な概念:
-directoryオブジェクトに属する属性は、(名前、値)ペアであり、属性は複数の値を持つことができます。
- ディレクトリとディレクトリサービス、ディレクトリはディレクトリオブジェクトのコレクションです。ディレクトリサービスは、ディレクトリに保存されているオブジェクトのプロパティを作成、削除、変更するためのディレクトリ関連サービスを提供します。
- 検索と検索フィルター、ディレクトリオブジェクトを取得する操作は検索です。フィルターは、検索条件に似たオブジェクトです。
基本的な使用
²JNDIプロバイダーを登録する前に、JNDIを使用する前に、JNDIプロバイダーを取得してシステムに登録する必要があります。 JNDIに関連するシステムプロパティは、javax.naming.context、一般的に使用されるプロパティで定義されています。
-java.naming.factory.initial、Service ProviderがinitialContextを作成するために使用されるクラス名。
-java.naming.provider.url、initialContextの初期URLを構成するために使用される
-java.naming.factory.object、nameclasspairおよび参照に使用される名前からオブジェクトへのマップの作成に使用されるクラス。
-java.naming.factory.state、JNDI状態の作成に使用されるクラス。ディレクトリサービスの場合、通常、セキュリティ設定が必要であり、通常使用されます。
-java.naming.security.authentication、セキュリティタイプ、3つの値:なし、シンプルまたは強い値。
-java.naming.security.principal、認証情報。
-java.naming.security.credentials、証明書情報。
-java.naming.security.protocol、セキュリティプロトコル名。
System.setPropertyに登録します。プログラムが命令を表示しない場合、Javaは登録を完了するためにclassPathのjdni.propertiesファイルを探します。 jdni.propertiesの例:
java.naming.factory.initial = com.codeline.db.mockinitialcontextfactory
接続サービス
登録後、サービス接続を実装できます。名前サービスの場合は、initialContextから始めて、ディレクトリサービスはintialitydircontextを使用します。それぞれコンテキストとdircontextを実装します。これらの2つのインターフェイスは、名前サービスとディレクトリサービスのインターフェイスに対応し、JNDIで最も重要な2つのインターフェイスでもあります。
接続名サービス:
System.SetProperty(Context.Initial_Context_Factory、 "com.sun.jndi.fscontext.fscontextFactory"); intialitycontext ctx = new initialContext();
ディレクトリサービスへの接続:
ハッシュテーブルenv = new Hashtable(); env.put(context.initial_context_factory、 "com.sun.jndi.ldap.ldapctxfactory"); env.put(context.provider_url、 "ldap://myserver.com/"); env.put(context.security_authentication、 "simple"); // LDAPサーバーにログインするために必要なユーザー名はenv.put(context.security_principal、 "ldapuser"); // ldapにログインサーバーが必要とするパスワードはenv.put(context.security_credentials、 "mypassword"); InitialDircontext ctx = new initialdircontext(env);
マルチサービスプロバイダー:アプリケーションに複数のサービスプロバイダーが含まれている場合、接続するとわずかに異なります。例として名前サービスを受け取ります
ハッシュテーブルenv = new Hashtable(); env.put(context.initial_context_factory、 "com.sun.jndi.rmi.registry.registrycontextfactory"); env.put(context.provider_url、 "rmi://myserver.com:1099"); //異なるコンストラクターInitialContext ctx = new initialContext(env);を使用します。
オブジェクトを見つけます
名前サービスであろうとディレクトリサービスであろうと、ルックアップはオブジェクトを見つけるために使用されます。文字列をパラメーターとして使用することに加えて、Lookupは名前インターフェイスをパラメーターとして使用することもできます。
Greeter Greeter =(Greeter)ctx.lookup( "sayhello");
コンテキストですべてのオブジェクト名を取得する場合は、LISを使用してNameClassPairリストを返します。 Nameclasspairには、オブジェクト名とオブジェクトクラス名が含まれています。オブジェクトインスタンスの実際のリストを取得する場合は、バインディングリストを返すListBindingsを使用します。バインディングは、オブジェクトのインスタンスを含むNameclasspairのサブクラスです。
- リスト
namingEnumeration list = ctx.list( "awt"); while(list.hasmore()){nameclasspair nc =(nameclasspair)list.next(); System.out.println(NC); } -listBindings
namingEnumeration bindings = ctx.listbindings( "awt"); while(binding.hasmore()){バインディングbd =(バインディング)bindings.next(); System.out.println(bd.getName() + ":" + bd.getObject()); }
オブジェクトバインディング
- バインドを使用してバインディングを追加します
フルーツフルーツ= new Fruit( "Orange"); ctx.bind( "favorial"、fruit);
-Rebindを使用してバインディングを変更します
フルーツフルーツ=新しいフルーツ( "レモン"); ctx.rebind( "お気に入り"、フルーツ);
- バインドを使用してバインディングを削除します。
ctx.unbind( "Favorial");
オブジェクトの名前を変更します
名前を使用して、コンテキスト内のオブジェクトの名前を変更します
ctx.rename( "report.txt"、 "old_report.txt");
- 属性属性の取得に関連するインターフェイスは、属性と属性であり、どちらもjavax.naming.directoryパッケージにあります。 dircontextのgetattributesメソッドを介してオブジェクトの属性を設定し、属性のgetメソッドを使用して対応する属性を取得できます。最後に、属性のgetメソッドを使用して属性値を取得できます。
string dn = "uid = me、dc = mycompany、dc = com、ou = customer、o = examplearpp";コンテキストユーザー=(コンテキスト)ctx.lookup(dn); //すべての属性属性属性= user.getattributes( "");属性テスト= attrs .get( "test"); Object testValue = test.get();
上記の例では、ユーザーのすべての属性が取得されます。実際の使用では、ネットワーク帯域幅の影響を考慮すると、取得する属性のリストを設定できます。
string reqd_attrs = new String [] {"surname"、 "inverys"、 "title"、 "rfc822mailalias"};属性属性= user.getattributes( ""、reqd_attrs);
見つけてフィルタリングします
検索方法を使用して完了します。
public dircontext [] finduser(string inverations、string surname、string country、string phone){//構築条件Basicattributes search_attrs = new Basicattributes(); search_attrs.put( "Iniverss"、hients); search_attrs.put( "sn"、inciss); search_attrs.put( "c"、country); if(電話!= null)search_attrs.put( "PhoneNumber"、電話); namingEnumeration results = initial_ctx.search( "ou = customer、o = exampleapp"、search_attrs); linkedlist fund = new LinkedList(); while(results.hasmore()){searchResults sr =(searchResults)results.next();文字列名= sr.getName();オブジェクトctx = sr.getobject(); if((ctx == null)||!(ctx instanceof dircontext))fund.add(initial_ctx.lookup(name)); else fund.add(ctx); } dircontext [] ret_val = new dircontext [fund.size()]; fund.toarray(ret_val); Ret_valを返します。 }
dircontextインターフェイスのメインフィルタリング方法:
1。フィルター文字列を使用します
string reqd_attrs = new String [] {"cn"、 "uid"、 "rfc822mailalias"}; namingEnumeration results = initial_ctx.search( "ou = customer、o = exampleapp"、search_attrs、reqd_attrs);
2. SearchControlsを使用して、より多くの制御を取得します
searchControls ctrls = new SearchControls(); ctrls.setCountlimit(20); ctrls.settimelimit(5000); ctrls.setearchscope(searchcontrols.subtree_scope); namingEnumeration results = initial_ctx.search( "cat = books、ou = crowts、o = examplearpp"、 "title =*java*"、ctrls);
プロパティを変更します
DircontextとinitialDircontextのModiyAttributesメソッドを使用して行われます。いわゆる変更プロセスは、実際に変更する属性のリストを最初に構築し、上記の方法を使用して送信することです。プロパティに複数の値が含まれている場合、プロパティの変更されていない値を含める必要があります。そうしないと、サーバーが不要になった場合、サーバーはそれらの値を削除します。
public void updateaddress(string dn、stringアドレス、string countre、string phone){basicattributes mod_attrs = new basicattributes(); if(address!= null)mod_attrs.put( "address"、address); if(country!= null)mod_attrs.put( "c"、country); if(電話!= null)mod_attrs.put( "PhoneNumber"、電話); if(mod_attrs.size()!= 0)initial_ctx.modifyattributes(dn、dircontext.replace_attribute、mod_attrs); } ModificationItemを使用すると、複数の異なる変更操作を一度に実行することもできます。
ModificationItem [] mod_items = new ModificationItems [2];属性email = new BasicAttribute( "rfc822mailalias"、new_email); ModificationItem email_mod = new ModificationItem(dircontext.add_attribute、email);属性addr = new BasicAttribute( "アドレス"、アドレス); ModificationItem addr_mod = new ModificationItem(dircontext.replace_attribute、addr); mod_items [0] = email_mod; mod_items [1] = addr_mod; intial_ctx.modifyattributes(dn、mod_items);
コンテキストを作成します
createSubContextメソッドを使用して完了します。
basicattributes attrs = new BasicAttributes(); attrs.put( "イニシャル"、イニシャル); attrs.put( "sn"、inciss); attrs.put( "rfc822mailalias"、email); if(address!= null)attrs.put( "address"、address); if(country!= null)attrs.put( "c"、country); if(電話!= null)attrs.put( "PhoneNumber"、電話); intial_ctx.createsubcontext(dn、attrs);
コンテキストを削除します
DestrySubContextメソッドを使用して完了します。
intial_ctx.destroysubcontext(dn);
例
これが別の例です。
Tomcatのconf/server.xmlで構成:
<コンテキストパス= "/jndi"> <リソース名= "bean/mybeanfactory" auth = "container" type = "com.huawei.jndi.bean.mybean" factory = "org.apache.naming.factory.beanfactory" bar = "23"/> </context>
上記のTomcatでコンポーネントが宣言されており、コードでこのコンポーネントを取得できます。
try {context initcontext = new initialContext();コンテキストenvctx =(context)initcontext.lookup( "java:comp/env"); mybean bean =(mybean)envctx.lookup( "bean/mybeanfactory"); system.out.println(bean.getbar()); } catch(Exception e){e.printstacktrace(); }概要:TomcatでJNDIコンポーネントを構成し、コードに装備されたコンポーネントを取得します。
各WebコンテナのJNDI実装クラスは異なります。たとえば、JBossでは、JNDIプロビジョニングクラスはorg.jnp.interfaces.namingContextFactoryです。これはTomcatとは異なります。
この観点から、JNDIの役割は、Springの依存噴射の役割に似ています。ただし、JNDIを介して、アプリケーション全体およびドメイン全体でコンポーネントを取得することができます。サーバーAで構成されたコンポーネントは、別のサーバーBでJNDIを介して取得できます。
Springは、JNDIのカプセル化も提供します。これは、使用がより便利です。以下は例です。
<! - jndiテンプレート - > <bean id = "jnditemplate"> <プロパティ名= "環境"> <props> <prop key = "java.factory.initial"> org.jnp.interfaces.namingcontextfactory </prop> <prop key = "java.naming.provider.url"> 10.137.96.212:18199 </prop> <prop key = "java.factory.url.pkgs"> org.jnp.interfaces:org.jboss.naming </prop> </props> </propert < id = "jmsconnectionFactory"> <プロパティ名= "jnditemplate" ref = "jnditemplate" /> <プロパティname = "jndiname" value = "topicconnectionfactory" /> < /bean>
最初にjnditemplateを宣言し、ターゲットアドレスとJNDIサービスプロビジョニングクラスを構成します。次に、JNDIOBjectFactoryBeanを介して、JNDIコンポーネントを簡単に取得してタイプ変換を実行できます。