導入

このセクションでは、Spring LDAP について比較的簡単に導入します。内容は以下のとおりです。

概要

Spring LDAP は、Java での LDAP プログラミングを簡素化するために設計されています。このライブラリが提供する機能の一部は以下のとおりです。

  • JdbcTemplate (Javadoc) -LDAP プログラミングに対するスタイルテンプレートの簡素化。

  • JPA または Hibernate スタイルのアノテーションベースのオブジェクトとディレクトリのマッピング。

  • QueryDSL のサポートを含む、Spring Data リポジトリのサポート。

  • LDAP クエリと識別名の作成を簡素化するユーティリティ。

  • 適切な LDAP 接続プール。

  • クライアント側の LDAP 補正トランザクションのサポート。

従来の Java LDAP と LdapClient の比較

すべての人のストレージを検索し、その名前をリストで返すメソッドを考えてみましょう。JDBC を使用して接続を作成し、ステートメントを使用してクエリを実行します。次に、結果セットをループして目的の列を取得し、リストに追加します。

JNDI を使用して LDAP データベースに対して作業する場合、コンテキストを作成し、検索フィルターを使用して検索を実行します。次に、結果の名前の列挙をループし、必要な属性を取得してリストに追加します。

Java LDAP でこの人名検索メソッドを実装する従来の方法は、次の例のようになります。太字で示されているコードに注意してください。これは、メソッドのビジネス目的に関連するタスクを実際に実行するコードです。残りは接続機能です。

public class TraditionalPersonRepoImpl implements PersonRepo {
   public List<String> getAllPersonNames() {
      Hashtable env = new Hashtable();
      env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
      env.put(Context.PROVIDER_URL, "ldap://localhost:389/dc=example,dc=com");

      DirContext ctx;
      try {
         ctx = new InitialDirContext(env);
      } catch (NamingException e) {
         throw new RuntimeException(e);
      }

      List<String> list = new LinkedList<String>();
      NamingEnumeration results = null;
      try {
         SearchControls controls = new SearchControls();
         controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
         results = ctx.search("", "(objectclass=person)", controls);

         while (results.hasMore()) {
            SearchResult searchResult = (SearchResult) results.next();
            Attributes attributes = searchResult.getAttributes();
            Attribute attr = attributes.get("cn");
            String cn = attr.get().toString();
            list.add(cn);
         }
      } catch (NameNotFoundException e) {
         // The base context was not found.
         // Just clean up and exit.
      } catch (NamingException e) {
         throw new RuntimeException(e);
      } finally {
         if (results != null) {
            try {
               results.close();
            } catch (Exception e) {
               // Never mind this.
            }
         }
         if (ctx != null) {
            try {
               ctx.close();
            } catch (Exception e) {
               // Never mind this.
            }
         }
      }
      return list;
   }
}

Spring LDAP、AttributesMapper、LdapClient クラスを使用することで、以下のコードで全く同じ機能を実現できます。

import static org.springframework.ldap.query.LdapQueryBuilder.query;

public class PersonRepoImpl implements PersonRepo {
   private LdapClient ldapClient;

   public void setLdapClient(LdapClient ldapClient) {
      this.ldapClient = ldapClient;
   }

   public List<String> getAllPersonNames() {
      return ldapClient.search().query(
            query().where("objectclass").is("person")
         ).map((Attributes attrs) ->
            attrs.get("cn").get().toString()
         ).list();
   }
}

定型コードの量は、従来の例よりも大幅に少なくなります。LdapClient 検索メソッドは、DirContext インスタンスが作成されていることを確認し、検索を実行し、指定された AttributesMapper を使用して属性を文字列にマップし、文字列を内部リストに収集し、最後にリストを返します。また、NamingEnumeration と DirContext が適切に閉じられていることを確認し、発生する可能性のある例外を処理します。

当然、これは Spring Framework サブプロジェクトであるため、次のように Spring を使用してアプリケーションを構成します。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:ldap="http://www.springframework.org/schema/ldap"
       xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/ldap https://www.springframework.org/schema/ldap/spring-ldap.xsd">

   <ldap:context-source
          url="ldap://localhost:389"
          base="dc=example,dc=com"
          username="cn=Manager"
          password="secret" />

   <bean id="ldapClient" class="org.springframework.ldap.core.LdapClient" factory-method="create">
        <constructor-arg ref="contextSource" />
    </bean>

   <bean id="personRepo" class="com.example.repo.PersonRepoImpl">
      <property name="ldapClient" ref="ldapClient" />
   </bean>
</beans>
カスタム XML 名前空間を使用して Spring LDAP コンポーネントを設定するには、前述の例のように、XML 宣言にこの名前空間への参照を含める必要があります。

パッケージの概要

Spring LDAP を使用するには、最低限以下のものが必要です。

  • spring-ldap-core: Spring LDAP ライブラリ

  • spring-core: フレームワークによって内部的に使用されるその他のユーティリティクラス

  • spring-beans: Java Bean を操作するためのインターフェースとクラス

  • slf4j: 内部で使用される単純なロギングファサード

必須の依存関係に加えて、特定の機能には次のオプションの依存関係が必要です。

  • spring-data-ldap: リポジトリサポートなどの基本インフラストラクチャ

  • spring-context: アプリケーションが Spring アプリケーションコンテキストを使用して接続されている場合に必要です。spring-context は、アプリケーションオブジェクトが一貫した API を使用してリソースを取得する機能を追加します。BaseLdapPathBeanPostProcessor を使用する予定がある場合は、必ず必要です。

  • spring-tx: クライアント側の補正トランザクションサポートを使用する場合に必要です。

  • spring-jdbc: クライアント側の補正トランザクションサポートを使用する場合に必要です。

  • commons-pool: プーリング機能を使用する場合に必要です。

  • spring-batch: LDIF 解析機能を Spring Batch と一緒に使用する場合に必要です。

spring-data-ldap は推移的に spring-repository.xsd を追加し、spring-ldap.xsd は spring-repository.xsd を使用します。そのため、Spring LDAP の XML 設定サポートは、Spring Data の機能セットが使用されていない場合でも、この依存関係を必要とします。

入門

これらのサンプル [GitHub] (英語) は、一般的なユースケースで Spring LDAP を使用する方法を示す有用な例をいくつか提供しています。

サポート

質問がある場合は、spring-ldap タグを使用したスタックオーバーフロー (英語) で質問してください。プロジェクトの Web ページは spring.io/spring-ldap/ です。

謝辞

Spring LDAP プロジェクト開始当初の取り組みはジェイウェイ (英語) によって支援されました。現在、プロジェクトの維持管理はピボタル によって資金提供されており、その後 VMware (英語) に買収されました。

プロジェクト構造をチェックするのに便利なオープンソースライセンスを提供してくれたストラクチャー 101 (英語) に感謝します。