前へ     目次     索引     DocHome     次へ     
iPlanet Application Server 移行ガイド



第 4 章   NAS 2.1 アプリケーションの移行


この章では、NAS 2.1 アプリケーションを変更して、iPlanet Application Server 6.5 プログラミングモデルに適合させる方法について説明します。

この章には次の節があります。



アプリケーションの再設計

既存のアプリケーションを設計し直す場合は、ある部分に対して行った変更によってほかの部分も影響を受けることを念頭におくことが重要です。

アプリケーションを次のいずれかのモデルとして考えると有益です。

  • 目的を達成するための一連のユーザ対話。たとえば、オンライン調査または標準化されたテストなど

  • 中心となるフロントページを持つ業務情報センター。たとえば、複数の業務 (引き出しや振り込みなど) に通じている中心のページを持つオンラインバンクなど

実際には、アプリケーションはこれらの 2 つの組み合わせです。たとえば、オンラインバンクは中央業務情報センターであり、そこからの各経路は目的を達成するための一連のユーザ対話に通じています。

ただし、アプリケーションが細分化されている場合でも、一部分ずつ移行することが多くの場合で最適な方法です。詳細については、「コンポーネントの部分的移行」を参照してください。



プレゼンテーションロジックの移行



この節では、次の概念について説明します。


Servlet としての AppLogic の再作成

AppLogic は Servlet に直接マッピングされます。AppLogic と Servlet はともに、URL によって呼び出されます。また、入力の処理および出力の生成を行うメカニズムを持っています。コード自体のレイアウトを除く主な相違点は、AppLogic がビジネスロジックを実行するのに対して通常、Servlet は実行しないという点です。ビジネスロジックは EJB で処理され、Servlet によって参照されます。同様に、プレゼンテーションレイアウトは JSP で処理され、Servlet によって参照されます。つまり、Servlet とは、別個のエンティティにビジネスロジックが再実装された AppLogic のようなものです。

Servlet については、『開発者ガイド』の第 3 章「Servlet によるアプリケーションの制御」を参照してください。

Servlet は service() メソッドを含んでいる必要があります。 HTTP Servlet では、HTTP 転送方式に応じて doGet()doPost() などとして実装されていることもあります。このメソッドは、AppLogic の execute() メソッドと論理的にほぼ同じです。これはコンポーネントの主な実行フローです。

さらに、AppLogic では、受信データを格納する IValList メンバー変数が iPlanet Application Server によって作成されるのに対し、Servlet では、iPlanet Application Server によってリクエストオブジェクトが作成され、パラメータとして Servlet に渡されます。同様に、AppLogic では IValList を使って出力するのに対し、Servlet ではレスポンスオブジェクトを使って出力し、パラメータとして Servlet に渡します。次のコードサンプルは両方のケースを示しています。


AppLogic

public class MyAppLogic extends AppLogic {
    public void execute () throws IOException {
    ...
    String lastName = valIn.getValString("lastName");
    ...
    return result ("<html><body>¥n"
                 + "<p>Your last name is " + lastName + ".¥n"
                 + "</body></html>¥n");
    }
}


Servlet

public class myServlet extends HttpServlet {
public void service (HttpServletRequest req,
                     HttpServletResponse res)
            throws IOException, ServletException
    {
    ...
    res.setContentType("text/html");
    String lastName = req.getParameter("lastName");
    ...
    PrintWriter output = res.getWriter();
    output.println("<html><body>¥n");
                 + "<p>Your last name is " + lastName + ".¥n"
                 + "</body></html>¥n");
    }
}

JSP および Servlet は観点が異なるほぼ同じエンティティであるため、AppLogic を JSP として再実装することもできます。次のようにします。

<html><body>
<p>Your last name is <display property="request:params:lastName">.
</body></html>

Servlet については、『開発者ガイド』の第 4 章「JavaServer Pages (JSP) によるアプリケーションページの表示」を参照してください。


プレゼンテーションレイアウトの再作成

ある意味では、2.1 HTML テンプレートはすでに移行されています。iPlanet Application Server 6.5 テンプレートエンジンは、このテンプレートが JSP であるかのように簡単にコンパイルします。新しいテンプレートエンジンには互換性があり、階層型クエリを除く GX タグをサポートしています。

ただし、JSP では GX タグのサポートが廃止されているため、これらのテンプレートを変換して標準の JSP タグおよびシンタックスを使う必要があります。JSP は Beans を使って出力パラメータをカプセル化するため、任意の Java オブジェクトにもアクセスできます。JSP から EJB に直接アクセスすることもできます。ただし、通常は、Servlet の実行時にリクエストオブジェクト内の属性を設定し、JSP 内でそれらの属性を呼び出します。

例を含む JSP の詳細については、『開発者ガイド』の第 4 章「JavaServer Pages (JSP) によるアプリケーションページの表示」を参照してください。


セッションとセキュリティの再作成

iPlanet Application Server 6.5 セッションでは HttpSession インターフェイスが使われます。API は異なりますが、その概念は NAS 2.1 セッションと似ています。Servlet (または AppLogic) によってセッションが作成され、これによってユーザセッションが存在する限り持続するセッションオブジェクトがインスタンス化されます。セッション cookie はクライアントに返され、次にクライアントと対話するときに再度読み込まれます。セッションが存在すれば、そのセッションにオブジェクトをバインドできます。

Servlet のセキュリティは変更されています。詳細については、『開発者ガイド』を参照してください。



ビジネスロジックの移行



iPlanet Application Server 6.5 では、AppLogic ではなく、Enterprise JavaBeans (EJB) によってビジネスロジックが処理されます。AppLogic と EJB の重要な相違点は、EJB はユーザとの「セッション」の間持続させることができ、セッション Beans の場合はユーザのセッションとは別に指定されるという点です。エンティティ Beans はユーザと無関係に存在するため、サーバが存在する限り持続する可能性があります。

別々のタスクを実行するこれらの EJB を記述し、Servlet からそれらの Beans に接続します。たとえば、電子ショッピングカートを利用する場合にこの方法を使います。

JDBC とトランザクションサポートの詳細については、第 7 章「EJB のトランザクション処理」、および『iPlanet Application Server 開発者ガイド』の第 8 章「JDBC を使ったデータベースアクセス」を参照してください。



データアクセスロジックの移行



この節では、JDBC API を使ったデータベース呼び出しの再配置について説明します。

iPlanet Application Server 6.5 の JDBC レイヤは、JDBC 2.0 の仕様および標準エクステンションのすべてをサポートしています。

JDBC とトランザクションサポートの詳細については、第 8 章「EJB のトランザクション処理」、および『開発者ガイド』の第 9 章「JDBC を使ったデータベースアクセス」を参照してください。

$GX_ROOTDIR/solarisdbg/JDK_1.1/java (または同様のディレクトリ) の JDBC 2.0 インタフェースは、CLASSPATH のほかの JDBC インタフェースよりも前に記述されている必要があります。iPlanet Application Server 6.5 は $JAVA_HOME/lib/rt.jar に JDBC 2.0 インタフェースがある JDK 1.1 とともに動作するので、この rt.jar は iPlanet Application Server のクラスよりも後になるようにします。次のようになります。

setenv CLASSPATH :$GX_ROOTDIR/solarisdbg/JDK_1.1:...:$JAVA_HOME/lib/rt.jar:...


不適合エラー

次のようなログメッセージが返される場合、CLASSPATH 内の JDBC 2.0 インターフェイスの前に JDBC 1.2 インターフェイスがある可能性があります。

[01/05/99 11:25:51:0] error:APPLOGIC-caught_exception:Caught Exception:
java.lang.NoSuchMethodError:java.sql.Statement:method
addBatch(Ljava/lang/String;)V not found



コンポーネントの部分的移行

この節では、以前のコンポーネント (Java および C++ AppLogic) を新しいコンポーネント (Servlet および EJB) とともに使う方法について説明します。次の 4 つの組み合わせがサポートされています。


Java AppLogic からの EJB の呼び出し

Servlet と EJB 間で共有される特別なコンテキストはないため、Servlet から呼び出す場合と同じ方法で AppLogic から EJB を呼び出します。

次の例は、ShoppingCart という EJB にアクセスする AppLogic を示しています。AppLogic は、カートのリモートインターフェイスをインポートしてからユーザのセッション ID を ShoppingCart に割り当てることによって、カートに対するハンドルを作成します。カートはユーザのセッション内に保存されます。

import cart.ShoppingCart;
% // ユーザのセッションおよびショッピングカートを取得します。
    // まずセッションを作成します。
    ISession2 sess = createSession(GXSESSION.GXSESSION_DISTRIB,
                                   0,           //no timeout
                                   "callEjb",    //アプリケーション名
                                   null,        //システム生成 ID
                                   null);

    //IValList を作成してセッションのショッピングカートに保存します。
    IValList ival = sess.getSessionData();

    ShoppingCart cart = (ShoppingCart)ival.getVal("shoppingCart");

    // ユーザがカートを持っていない場合は新規に作成します。
    if (cart == null) {
        cart = new ShoppingCart();
        ival.setVal("shoppingCart", cart);
    }

Java Naming Directory Interface (JNDI) を使って EJB に対するハンドルまたはプロキシを確立することによって、EJB にアクセスできます。その後は EJB を正規オブジェクトとして参照でき、すべてのオーバーヘッドはビーンのコンテナによって管理されます。

次の例は、ショッピングカートのプロキシを検索するための JNDI の使用法を示しています。

String jndiNm = "Bookstore/cart/ShoppingCart";
javax.naming.Context initCtx;
Object home;
    try {
         initCtx = new javax.naming.InitialContext(env);
    } catch (Exception ex) {
          return null;
    }
    try {
          java.util.Properties props = null;
          home = initCtx.lookup(jndiNm);
    }
    catch(javax.naming.NameNotFoundException e)
    {
          return null;
    }
    catch(javax.naming.NamingException e)
    {
          return null;
    }
    try {
          IShoppingCart cart = ((IShoppingCartHome) home).create();
          ...
} catch (...) {...}


Java AppLogic からの Servlet の呼び出し

AppLogic から JSP を呼び出す場合などに、GXContext.NewRequest() または GXContext.NewRequestAsync() を使って Java AppLogic から Servlet を呼び出すことができます。NewRequest() の詳細および具体例については、『iPlanet Application Server Foundation Reference』の GXContext クラスの説明を参照してください。

インスタンス化すると、JSP および Servlet は同じタイプのオブジェクトであるため、AppLogic から JSP を呼び出すこともできます。

次の例は、Servlet の Servlet エンジン (ServletRunner という AppLogic) と同じプロセス呼び出しを使って AppLogic から Servlet を呼び出す方法を示しています。

class SomeApplogic extends Applogic {
   int execute() {
      valIn.setValString("appName","nsOnlineBank");
      valIn.setValString("servletName","Login");
      valIn.setValString("SCRIPT_NAME","nsOnlineBank/Login");
      com.netscape.servlet.servletrunner.ServletRunner sr =
         new com.netscape.server.servlet.servletrunner.ServletRunner();
      sr.valIn = valIn;
      sr.valOut = valOut;
      sr.context = context;
      sr.stream = this.stream;
      sr.ticket = this.ticket;
      sr.request = this.request;
      sr.COMSet(COMGet());
      sr.COMAddRef();
      sr.execute();
      ...
   }
}

次の例は、NewRequest() を使って新しいプロセス内で AppLogic から Servlet を呼び出す方法を示しています。

class SomeApplogic extends Applogic {
    int execute() {
        valIn.setValString("appName","nsFortune");
        valIn.setValString("servletName","fortune");
        valIn.setValString("SCRIPT_NAME","nsOnlineBank/Login");
        retValue = GXContext.NewRequest(m_Context,
                                   "ApplogicServlet_nsFortune_fortu ne",
                                   valIn,valOut,host,port,0);
        ...
    }
}

次の例のように、ほとんど同じ方法で JSP を呼び出すことができます。

public class SomeApplogic extends Applogic {
    int execute() {
        valIn.setValString("appName","System");
        valIn.setValString("servletName","JSPRunner");
        valIn.setValString("JSP","nsOnlineBank/jsp/abc.jsp");
        valIn.setValString("SCRIPT_NAME","nsOnlineBank/Login");
        retValue =
            GXContext.NewRequest(m_Context,
                                 "Applogic Servlet_System_JSPrunner",
                                 valIn,valOut,host,port,0);
    ...
    }
}

次の例は、GUID を使って Servlet を呼び出す方法を示しています。

public class SomeApplogic extends Applogic {
    int execute() {
        valIn.setValString("appName","nsFortune");
        valIn.setValString("servletName","fortune");
        newRequest("{6F3547D0-FDCB-1687-B323-080020A16896}",
                   valIn,valOut,0);
    }
}


Servlet からの Java AppLogic の呼び出し

GXContext.NewRequest() または GXContext.NewRequestAsync() を使って、Servlet から AppLogic を呼び出すことができます。詳細および具体例については、『iPlanet Application Server Foundation Class Reference』の GXContext クラスの説明を参照してください。

NewRequest() を使って AppLogic を呼び出すには、サーバのコンテキストを IContext オブジェクトに割り当ててから AppLogic の入出力 IValList オブジェクトを設定します。

次の例は、IContext オブジェクトを取得して、AppLogic のパラメータを設定してから、最後に NewRequest() を使って AppLogic を呼び出す方法を示しています。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.kivasoft.applogic.*;
import com.kivasoft.types.*;
import com.netscape.server.servlet.extension.*;

public class callAnAppLogic extends HttpServlet {

    public void service(HttpServletRequest req,
                        HttpServletResponse res)
        throws ServletException, IOException
    {
        // IContext のハンドルである ic をまず設定します。
        ServletContext sctx = getServletContext();
        com.netscape.server.IServerContext isc;
        isc = (com.netscape.server.IServerContext) sctx;
        com.kivasoft.IContext ic = isc.getContext();

        // IValLists と GUID を設定します。
        IValList vi = GX.CreateValList(); // valIn
        valIn.setValString("randomParameter", "Cirdan the Shipwright");

        IValList vo = GX.CreateValList(); // valOut

        String al = req.getParameter("AppLogicToCall");
                      // AppLogicToCall のリクエストを待ちます。

        //最後に AppLogic を呼び出します。
        GXContext.NewRequest(ic, al, vi, vo, 0);
    }
}


Servlet の AppLogic へのアクセス

各 Servlet は AppLogic 内に含まれています。iPlanet Application Server 機能インターフェイス HttpServletRequest2 でメソッド getAppLogic() を使って、Servlet を制御する AppLogic インスタンスにアクセスすることができます。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.kivasoft.applogic.*;
import com.kivasoft.types.*;
import com.netscape.server.servlet.extension.*;7

public class callAnAppLogic extends HttpServlet {

    public void service(HttpServletRequest req,
                        HttpServletResponse res)
        throws ServletException, IOException
    {
        HttpServletRequest2 req2 = (HttpServletRequest2)req;
        AppLogic al = req2.getAppLogic();
        //al はスーパークラスへのハンドルです。
        ...
    }
}


Servlet からの C++ AppLogic の呼び出し

「Java AppLogic からの Servlet の呼び出し」で説明したように、メソッド GXContext.NewRequest() は GUID によって AppLogic を呼び出し、オブジェクトに対するハンドルを入出力パラメータとして提供します。AppLogic は Java 特有のハンドルによって呼び出されるのではなく、特定の名前または GUID によって呼び出されるため、このメソッドは Java AppLogic だけでなく C++ AppLogic も呼び出します。「Servlet からの Java AppLogic の呼び出し」で示した例を参照してください。


部分的に移行したアプリケーションのセッション

HttpSession2 インターフェイスは、セッションオブジェクトに直接アクセスできるようにする追加のセッションインターフェイスです。このインターフェイスを使うと、AppLogic と Servlet 間でセッション (および結果的にデータ) を共有できます。

Servlet では、セッションは HttpSession のインスタンスです。これに対し、AppLogic では、セッションデータは IValList オブジェクトです。AppLogic では Integer、String、および blobs (バイト配列) がセッションに保存されるのに対し、Servlet では直列化可能なオブジェクトがセッションに保存されます。その結果、AppLogic でセッションに保存されるものと Servlet でセッションに保存されるものとの間に直接のマッピングはありません (文字列を除く)。

HttpSession2 インターフェイスによって、セッションデータ共有の問題が解決されます。HttpSession2 には Integer、String、blobs、およびユーザログインデータの保存および取得を行うメソッドがあります。これらのメソッドは AppLogic 開発者が使うものと類似するメソッドです。このように、HttpSession2 を使うと、セッションは AppLogic と Servlet 間で交互に動作させることができます。

HttpSession2loginSession( ) および logoutSession( ) によって、Servlet で AppLogic セッション API を共有することができます。これらのメソッドは iPlanet Application Server 6.5 では廃止されているものです。AppLogic の場合と同様に、これらの 2 つのメソッドは通常、isAuthorized( ) とともに使われます。また、Servlet はアクセス制御リストに登録されるため、AppLogic で確立された安全なセッションを Servlet で使うことができ、その逆も可能です。

詳細については、『開発者ガイド』の第 12 章「安全なアプリケーションの作成」を参照してください。


セッションの表示

セッションが cookie によって制御されるため、デフォルトでは AppLogic で作成されたセッションは Servlet に表示されません。これは cookie がドメインおよび URI に依存しており、Servlet の URI が AppLogic の URI と異なるためです。この問題を回避するには、AppLogic でセッションを作成するとき、saveSession() を呼び出す前に setSessionVisibility() を呼び出します。

セッションの保存によってもセッション cookie が作成されるため、 saveSession() を呼び出す前に setSessionVisibility() を呼び出すことが重要です。

たとえば、AppLogic では次の例について検討します。

domain=".mydomain.com";
path="/"; //すべてのドメインに表示します
isSecure=true;
if ( setSessionVisiblity(domain, path, isSecure) == GXE.SUCCESS )
    { //セッションはすべてのドメインに表示されています }

セッションの詳細については、『開発者ガイド』の第 11 章「ユーザセッションの作成と管理」 を参照してください。


ITemplateData から ResultSet への変換

NAS 2.1 では、HTML テンプレート処理に使われる階層型データソースを表現するための ITemplateData というインターフェイスが用意されていました。NAS 2.1 の ITemplateData IGXTemplateData (Java) は、一組のメモリベースの階層型データ内で行を繰り返したり、列の値の取得を行うメソッドを提供しています。iPlanet Application Server 6.5 ではこの機能はサポートされていませんが、グループ名はサポートされています (必須)。

iPlanet Application Server 6.5 では ITemplateData 機能が JDBC ResultSet オブジェクトに置き換えられています。BaseUtils クラスからメソッド convertITemplateDataToResultSet() を使って ITemplateData オブジェクトを ResultSet オブジェクトに変換できます。具体的な使用法については、『iPlanet Application Server Foundation Class Reference』の BaseUtils クラスの説明を参照してください。次の例は、AppLogic における ITemplateDataResultSet への変換を示しています。変換メソッドにパラメータとしてデータグループ名を渡す必要があります。

ITemplateData itd = GX.CreateTemplateDataBasic("myTemplateData");
... // myTemplateData を設定します。
...
ResultSet rs = BaseUtils.convertITemplateDataToResultSet("dataGroup1",itd);


前へ     目次     索引     DocHome     次へ     
Copyright © 2002 Sun Microsystems, Inc. All rights reserved.

最新更新日 2002 年 3 月 6 日