February 28, 2008

mixiがOpenIDプロバイダに

先日、こんなニュースが流れてきました。

OpenIDファウンデーション・ジャパン設立へ--ミクシィやヤフーも参加
http://japan.cnet.com/news/media/story/0,2000056023,20368347,00.htm

mixiやYahoo!JapanがOpenIDプロバイダになります。
(Yahoo!Japanは既に対応済み)

mixiも、以前からOpeinIDのAPIを利用しているフシがあったので
そのうち正式にサービスとして公開するのかな・・・?とは思っていました。

楽天は完全に出遅れ感が・・・(^^;


OpenIDってなに?・・・という人のために。

mixiやYaoo!や楽天など、いろいろなネットサービスを使うようになる
とユーザーIDやパスワードの管理がだんだん難しくなりませんか?

このサイトのIDとパスワードって何だっけ・・・?って。

そこで、インターネットサービスをもっと利用しやすくしよう!
ということでいろんなWebサイトでID/パスワードを共通化しよう
という仕組みが考えられました。

この仕組み業界用語ではSSO(Single Sign On)と言います。
OpenIDはそのSSOという仕組みのうちの一つです。


OpenIDでは、単純にOpenIDに対応しているだけのサイト(コンシューマ)と
OpenIDのID/パスワードを発行するサイト(OpenIDプロバイダ)の2種類があり、
mixiやYahoo!JapanはOpenIDプロバイダになることを表明しました。

OpenIDに対応しているサイトなら
OpenIDプロバイダが発行するID/パスワードでログインできるようになります。

具体的には、OpenIDに対応しているサイトならどこでも
mixiやYahoo!のID/パスワードでログインできるようになるんです。


いろんなサイトにID/パスワードをばらまくのは不安・・・
という声もあるかと思いますが、OpenIDなら認証を行うのはOpenIDプロバイダなので、
他のサイトにIDやパスワードが漏れることはありません。
ログインするサイトは、OpenIDプロバイダから「このユーザは正しく認証されました」
という情報をもらうだけです。


OpenIDが広まれば、一つのID/パスワードで
いろんなサイトにログインできるようになるんです。

OpenIDが普及したら便利になると思いませんか?


今のところ、ネット「OpenID」を調べても
IT業界の人向けの情報ばかりというのが現状です。

OpenIDが普及するには、一般ユーザにも直感的にわかりやすく
受け入れられるマーケティング・プロモーション戦略が重要なのではないかと思います。
その辺のところをmixiやYahoo!には頑張ってもらいたいですね。

February 27, 2008

EJB3でのホームインタフェースの作成

どのWebサイトや雑誌記事を見ても「EJB3ではホームインタフェース不要」と、書いてありますが・・・

Stateful SessionBeanのセッション管理をアプリケーションで制御したい場合にはホームインタフェースが必要になる場面も多いと思います。

具体的な例のひとつは、アプリケーションで一旦セッションを破棄して新規にセッションを開始したい場合です。

@EJBアノテーションはコンテナがフィールドを初期化する時にしか動作しないため、EJBのビジネスインタフェース型のフィールドを定義して、@EJBアノテーションを付与する方法では、このようなシチュエーションに対応できません。


EJB3でホームインタフェースを利用する場合は、次のように実装します。

ホームインタフェースを作成する。

  • javax.ejb.EJBLocalHome(リモート呼び出しを行う場合は javax.ejb.EJBHome)インタフェースを継承して作成する。
  • 1つ以上のcreate()メソッドを定義する。戻り値の型は次の手順で作成するビジネスインタフェースの型、引数は任意(と言ってもSerializableな型)、javax.ejb.CreateException をthrowするように実装する。
  • create()メソッドは引数の数と型が異なるものをいくつでもオーバーロード可。

package study.ejb3.model.service;

import javax.ejb.CreateException;
import javax.ejb.EJBLocalHome;

/**
 * ホームインタフェース。
 * javax.ejb.EJBLocalHome または javax.ejb.EJBHome を継承して作成する。
 * 1つ以上の create() メソッドを定義する。戻り値の型は ビジネスインタフェースの型。
 * create() メソッドは javax.ejb.CreateException をthrowするように定義する。
 * create() メソッドは引数の数と型が異なるものをいくつでもオーバーロード可。
 */
public interface HogeServiceHome extends EJBLocalHome {

    /**
     * create() メソッド
     */
    public HogeService create() throws CreateException;

}


ビジネスインタフェースを作成する。
  • 通常のEJB3ビジネスインタフェースとは違い、ホームインタフェースを併用する場合は javax.ejb.EJBLocalObject(リモート呼び出しを行う場合は javax.ejb.EJBObject)インタフェースを継承して作成する。
  • 任意のビジネスメソッドを定義する。ただし、引数と戻り値は Serializableな型であること。これは通常のEJB3スタイルと同様。
  • また、後述するBean実装クラスで@Removeアノテーションを付けたメソッドをクライアントから呼び出せるようにするため、同メソッドを定義する。


package study.ejb3.model.service;

import java.rmi.RemoteException;

import javax.ejb.EJBLocalObject;

/**
 * ビジネスインタフェース.
 * javax.ejb.EJBLocalObjectまたはjavax.ejb.EJBObjectを継承して作成する。
 * 任意のビジネスメソッドを定義する。戻り値と引数はSerializableな型であること。
 *
 */
public interface HogeService extends EJBLocalObject {

    /**
     * ビジネスメソッド
     */
    public String businessMethod() throws RemoteException;

    /**
     * Bean実装クラスで@Removeアノテーションを付けるメソッド
     */
    public void destroy() throws RemoteException;

}


Bean実装クラスを作成する。
  • 通常のEJB3スタイルとは異なり、ビジネスインタフェースをimplementsしない。
  • create() メソッドの引数の数と型に対応したメソッドを実装し、@Initアノテーションを付ける。メソッド名は任意。アクセス修飾子は public、戻り値の型は void 。
  • 任意の名前のメソッドを実装し、@Remove アノテーションを付ける。アクセス修飾子は public、戻り値の型は void。
  • ビジネスインタフェースに定義したビジネスメソッドを実装する。javax.ejb.EJBException をthrowするように実装する。
  • クラス宣言部に @Stateful アノテーションを付ける。これは通常の EJB3スタイルと同様。
  • クラス宣言部に@LocalHome(リモート呼び出しを行う場合は@RemoteHome)アノテーションを付ける。引数に、ホームインタフェースのクラスオブジェクトを指定する。
  • クラス宣言部に@Local(リモート呼び出しを行う場合は@Remote)アノテーションを付ける。引数に、ビジネスインタフェースのクラスオブジェクトを指定する。
  • 上記2つの設定により、ホームインタフェース、ビジネスインタフェース、Bean実装クラスの3つが関連付けられる。従来のEJB2.xではデプロイメントディスクリプタ(配備記述子)ejb-jar.xmlで設定した内容。


package study.ejb3.model.service;

import javax.ejb.EJBException;
import javax.ejb.Init;
import javax.ejb.Local;
import javax.ejb.LocalHome;
import javax.ejb.Remove;
import javax.ejb.Stateful;

/**
 * Bean実装クラス。
 * 通常のEJB3スタイルとは異なり、ビジネスインタフェースをimplementsしない。
 * @Local(または@Remove)アノテーションで
 *                          関連づくビジネスインタフェースを指定する。
 * @LocalHome(または@RemoveHome)アノテーションで
 *                          関連づくホームインタフェースを指定する。
 */
@Stateful(name = "HogeService")
@Local(HogeService.class)          // ビジネスインタフェースのクラスオブジェクトを指定
@LocalHome(HogeServiceHome.class) // ホームインタフェースのクラスオブジェクトを指定
public class HogeServiceBean {

    /**
     * ビジネスメソッド
     */
    public String businessMethod() throws EJBException {
        return "Hello! Business Method!";
    }

    /**
     * ホームオブジェクトのcreate()メソッドが呼ばれたとき
     * (新規セッション開始時)に呼ばれる
     */
    @Init
    public void init() {
        System.out.println("init() が呼ばれた");
    }

    /**
     * クライアントからこのメソッドが呼ばれるとセッションが破棄される
     */
    @Remove
    public void destroy() {
        System.out.println("destroy() が呼ばれた");
    }

}


EJBクライアント(EJB呼び出し側)の実装。
  • EJBビジネスインタフェース型ではなく、ホームインタフェース型のフィールドを定義し、@EJBアノテーションを付ける。EJBオブジェクトと同様、ホームオブジェクトも@EJBでインジェクション可能。


@EJB
private HogeServiceHome home;


  • ホームオブジェクトの create() メソッドを呼び出すと、EJBオブジェクトを取得可能。同時に新規にセッションが開始される。


// セッションを開始。
HogeService service = home.create();


  • EJBオブジェクトの、@Remove が付いたメソッドを呼び出すとセッション破棄。


// セッションを破棄
service.destroy();


  • 新規にセッションを開始したい場合(EJBオブジェクトを新規に取得したい)は、再度ホームオブジェクトの create() メソッドを呼び出せばOK。


// セッションを改めて新規に開始。
service = home.create();


@EJBアノテーションはフィールド初期化時にしか動作しないため、ホームインタフェースを使わないと新規にセッションを開始したい場合(EJBオブジェクトを新規に取得したい)は、JNDIルックアップするコードを書かないといけないことになります。



・・・なんだか、EJB2.xとEJB3のスタイルが混在した、えらく中途半端なコードになってしまいますね(^^;