本文へジャンプ

ソフトウェア > Lotus > Lotus Developer Domain > 

Iris Today Archives

ドミノでのサーブレットの開発


Lotus Software
by Anthony Patton
レベル:上級者
対 象:Domino 5.0
原文の掲載:2001年2月1日

Iris Today Archivesの原文

インデックス
サーブレットの基本
JSDK について
サーバーの設定
サーブレットのプロパティー・ファイル
ドミノ設定ファイル
サーブレットのライフ・サイクル
サーブレットの構造
サーブレットの作成と実行
ドミノ・オブジェクトとの協調
ドミノ・フォームの結合
まとめ

ドミノ R5 では、Java サーブレットをサポートしており、アプリケーションの開発の際の選択の幅が広がりました。たとえば、ドミノ・エージェントの代わりにサーブレットを用いてドミノ・オブジェクトにアクセスしたり、サーブレットでサーバーでの処理を行うことができます。

この記事では、エージェントとサーブレットの相違点やサーブレットを使用するためのサーバーの設定、基本的なサーブレットの構造といった、サーブレットの基本的な内容についての紹介をします。そして、3つのサーブレットの例について詳細に説明をします。

この記事では、JavaScript になじみがあり、ドミノ・アプリケーションの設計について理解していることを前提にしています。


サーブレットの基本
サーブレットとは、サーバー上で実行される Java のプログラムのことで、CGI (Common Gateway Interface) アプリケーションや、ドミノ・エージェントと同様の機能を提供するものです。サーブレットの主な利点は、メモリー上に一回だけ読み込めば良いということです。これに対して、ドミノ・エージェントや CGI プログラムは、呼び出されるたびにメモリーに読み込まれます。一度読み込まれると、サーブレットに対するすべての呼び出しで、同一のインスタンスが用いられます。

ドミノ・エージェントやサーブレットは、同様の機能を提供しますが、実装の点では大きく異なります。エージェントがドミノ・データベース内に存在するのに対して、サーブレットは、ファイル・システム上に存在します。この違いによって、配布とセキュリティーの2点について注意すべき点があります。

ドミノ・エージェントは、データベース内に存在するという点に大きな利点があります。複製を用いて他のドミノ サーバーに配布されます。さらに、ドミノのセキュリティー・モデルによりエージェントのアクセス権が決定します。

逆に、サーブレットはファイル・システム上に存在するため、サーバーやファイル、ディレクトリーのセキュリティー機構によりアクセス権を制御します。デフォルトでは、サーブレットはサーバーのセキュリティー権限で実行されます。しかし、特定のユーザー ID とパスワードが必要となります。最後に、Windows NT 上でディレクトリーの複製を使用しない場合は、使用したいすべてのシステム上にサーブレット・ファイルをコピーするかインストールする必要があります。
 
上に戻る
 
JSDK について
標準的なドミノデザイナーの開発環境ではサーブレットの開発をサポートしていないので、サーブレットのコードの開発をするには、サード・パーティー製の開発環境や、サンのコマンド・ライン JDK を使用しなければなりません。(IBM の VisualAge for Java を用いた開発については、Iris Today の記事「VisualAge for Java を使ってドミノにサーブレットを作成する」をご覧ください。)

サーブレットを開発するために必要なクラスとして、サン・マイクロシステムズ社からJSDK (Java Servlet Development Kit) が無料で提供されています。さらに、JSDK はドミノに標準でインストールされています。JSDK.JAR ファイルがドミノをインストールしたディレクトリーに置かれます。たとえば、私のドミノ サーバーは D ドライブの r5server というディレクトリーにインストールされているので、そのファイルのパスは次のようになります。

D:\r5server\jsdk.jar

メモ:Jar ファイルは Java ファイルを圧縮するための標準形式です。これは、WinZip や PKZip、Windows の CAB ファイルと同様のものです。
上に戻る
 
サーバーの設定
ドミノ R5 には独自のサーブレット・マネージャーがありますが、IBM の WebSphere といった、サード・パーティーのサーブレット・エンジンを使用することもできます。(現在では、WebSphere は、ドミノでサポートしている唯一のサーブレット・エンジンです。)ドミノ・ディレクトリー内にあるサーバーの文書にはサーブレットの設定に関するセクションがあります。これらの設定は、[インターネットプロトコル] - [Domino Web Engine] タブの Java サーブレットの部分にあります。以下の例は、私のテスト・サーバーでのサーブレットの設定です。

Server document servlet settings


オプションについての解説
オプション 説明
Java サーブレット・サポート これによりサーブレットを使用の有無を設定します。[なし]、[Domino Servlet Manager]、[サードパーティーのサーブレットサポート] の中から値を選択します。
サーブレット URL パス これは、サーブレットにアクセスするために使用する URL のことです。適切に実行するために必要となるサーブレット関連のファイルがあるディレクトリーです。
クラス・パス 実行したいサーブレットを置く場所で、ローカルのディレクトリーを指定します。ドミノのサーブレット・マネージャーは、サーブレットをクラス・パスで指定されたディレクトリーに置きます。
サーブレット・ファイル拡張子 ドミノがサーブレットを参照する際に、必要となる URL ファイルの拡張子。コンマで区切ることで複数の拡張子を指定できます。
セッション状態トラッキング この設定を有効または無効にすることで、サーブレット・マネージャーはアイドル状態のセッションを終了させるかどうかを選択できます。アイドル状態のセッションの時間制限は次のフィールドで設定されます。
アイドル状態のセッションのタイムアウト 接続が終了するまでのまでの待機時間(分)です。これは、セッション状態のトラッキングが有効な場合のみ適用されます。デフォルトは 30 分です。
最大セッション数 同時に使用可能なアクティブなサーブレットのセッションの数。デフォルトは 1000 セッションです。
セッションの保持 この設定を有効または無効にすることで、セッションの情報をディスクに保存するかどうかを選択できます。

ドミノ・サーブレットは、Java 仮想マシン (JVM: Java Virtual Machine) とサーブレット・マネージャーの2つの部分に分けることができます。サーブレットが有効な場合、Java 仮想マシンは、HTTP サーバーが開始する前にロードされます。結果として、ドミノのサーブレット・マネージャーが使用される場合は、HTTP サーバーは Java 仮想マシンがロードされた後にロードされます。サード・パーティー製のサーブレット・マネージャーを使用する場合は、Java 仮想マシンがロードされるだけです。
 
上に戻る
 
サーブレットのプロパティー・ファイル
ドミノのサーブレット・エンジンは、サーブレットをロードしたときに標準的なパラメーターを指定するための設定ファイルをサポートしています。これは、servlets.properties という名前のファイルで、ドミノをインストールしたデータ・ディレクトリーに置かれます。たとえば、以下のようになります。

D:\r5server\data\servlets.properties

もしファイルを見つけられない場合、Windows のノート・パッドなどのテキスト・エディターを用いて簡単に作成できます。

サーブレットのプロパティー・ファイルで、別名や初期化引数、URL 拡張子マッピング、Web サーバーのスタートアップ時にサーブレットのロードを行うなどの設定ができます。また、コメントを挿入することもできます。

サーブレットの別名
alias 文は以下のような構文になります。

servlet.<alias-name>.code=<class-name>

初期化引数
プロパティー・ファイルで、サーブレットの初期化データを指定できます。サーブレットは ServletConfig.getInitParameter メソッドを用いてデータにアクセスできます。初期化の構文は以下のようになります。

servlet.<alias or class name>.initArgs=<name1=value1>,<name2=value2>

URL 拡張子マッピング
URL 拡張子マッピングの構文は以下のようになります。

servlet.<alias or class name>.extension=<extension> <extension> ...

起動時にロード
スタートアップの構文は以下のようになります。

servlets.startup=<alias or class> <alias or class> ...

以下に、HelloWorld.class (拡張子の .class はあっても無くても構いません) サーブレットに名前 (Test) を割り当てている servlets.properties ファイルを示します。初期化引数が割り当てられ、起動時にロードされます。

# Example servlets.properties file
servlet.Test.code = HelloWorld
servlet.Test.initArgs = 1, 2, 3
servlets.startup = Test


サーブレットを Web サーバーの起動時にロードすることで、その時点からメモリー上で利用できます。しかしながら、次のことに注意してください。サーブレットのコードに変更を加えた場合、ドミノ HTTP サーバーをシャットダウンし、再起動しなければ、その変更は反映されません。再起動のコマンドは次の通りです。

Tell HTTP restart

一般的な誤り
サーブレットの設定ファイルに関する一般的な誤りを以下に列挙します。
  • ファイルを誤ったディレクトリーに置く。ファイルはドミノのデータ・ディレクトリーに配置しなければなりません。
  • 誤った拡張子を使用する。ノート・パッドのような多くのエディターは、勝手に .TXT 拡張子をファイルに付けることがあります。
  • 間違ったファイル名を使用している。ファイル名はservlets.properties でなければなりません。
  • 大文字小文字の違いを無視している。ファイル名やサーブレットの名前と割り当てステートメントの大文字小文字は区別されます。
 
上に戻る
 
ドミノ設定ファイル
ドミノ サーバーでサーブレットを有効にすると、サーブレットに関する行がドミノの設定ファイル (domino.cnf) に追加されます。このファイルは、データ・ディレクトリーに配置され、以下のような行が含まれるはずです。

# Java Servlet Settings

ServerInit servlet:ServletInit d:\r5server\Data
Service /servlet/* servlet:ServletService*
ServerTerm servlet:ServletTerm

 
上に戻る
 
サーブレットのライフ・サイクル
先ほど述べたように、サーブレットは一度だけメモリー上にロードされます。ロードされると、init メソッドが実行されます。service メソッドはクライアントがサーブレットにリクエストを出すたびに実行され、クライアントのリクエストに応じて doPost や doGet メソッドが呼び出されます。

サーブレットは、次の2通りの方法でロードできます。サーブレット・マネージャーは、HTTP サーバーの起動時にservlets.properties ファイルの指定に従うか、クライアントから初期化の要求が来たときにロードします。そして HTTP のタスクをシャットダウンするときにサーブレットは廃棄 (メモリーから消去) されます。

できるかぎり serlvets.properties ファイルを通じてサーブレット・マネージャーを使用してください。これは、HTTP サーバーの起動時にロードすることで、クライアントのリクエストを滞りなく処理でき、サーブレットの最初と最近のリクエストでほぼ等しい応答時間を提供できます。
 
上に戻る
 
サーブレットの構造
HTTP リクエストは、get と post の2種類に分けることができます。get メソッドは URL の後ろに情報を付け加え、環境変数 query_string から利用します。post は、名前と値をペアにして情報を送ります。

サーブレットの開発には、JSDK から、javax.servlet と javax.servlet.http の2つのパッケージが提供されており、post や get メソッドと共に機能します。これらのパッケージは Java サーブレットにインポートされます。

理解しておくべき重要な3つのメソッドを以下に挙げます。
  • service
    このメソッドはサーバーがサーブレットにリクエストを発行するたびに呼び出されます。通常、このメソッドは HTTP サーブレットでは使用されません。これは一般的なサービスに適しています。
  • doPostWeb
    サーバーからサーブレットに発行されるすべての post リクエストはこのメソッドを起動します。フォーマットは以下のようになります。
    public void doPost(HttpServletRequest req, HttpServletResponse res)
  • doGet
    Web サーバーからサーブレットに発行されるすべての get リクエストはこのメソッドを起動します。フォーマットは以下のようになります。
    public void doGet(HttpServletRequest req, HttpServletResponse res
最も頻繁に使用する2つのメソッドは、doPost と doGet です。各メソッドは、HttpServletRequest と HttpServletResponse の2つのパラメーターを取ります。

HttpServletRequest
HttpServletRequest オブジェクトには、クライアントからのリクエストに関するすべての情報が含まれています。このオブジェクトはリクエスト・ヘッダーや CGI 変数、クッキー、フォーム・データにアクセスしたり、セッションの追跡を行うために使用されます。実際には、到着したフォーム・データを調べて、サーブレットのパラメーターに格納します。

HttpServletRequest クラスのメソッド
メソッド 説明
getContentLength コンテント長をバイト単位で返します。
getContentType コンテントの MIME タイプを返します。
getCookies クッキー・オブジェクトの配列を返します。
getMethod 利用している HTTP メソッドを返します。
getParameter(String name) 指定したパラメーターの値を返します。サーブレット・エンジンはすべての HTML フォームの値をパラメーターに配置します。このメソッドは単一値のパラメーターで利用します。
getParameterValue(String name) 接続が終了するまでのまでの待機時間(分)です。これは、セッション状態のトラッキングが有効な場合のみ適用されます。デフォルトは 30 分です。
getQueryString リクエスト元の URL から Query string を返します。
getRemoteUser (もしあれば) リクエストしたユーザーの名前を返します。

HttpServletResponse
HttpServletResponse オブジェクトは、サーブレットからクライアントなどのリクエスト元への通信のために使用されます。メソッドの一部を以下に示します。

HttpServletResponseクラスのメソッド
メソッド 説明
getWriter 応答データをリクエスト元に送るための PrintWriter オブジェクトを返します。
sendRedirect(String url) 指定した URL に応答をリダイレクトします。
setContentType(String type) リクエスト元に送るコンテントのタイプを設定します。
setStatus(int code) HTTP の状態コードを設定します。
 
上に戻る
 
サーブレットの作成と実行
ここで、簡単なサーブレットの例を取り上げます。最初の4行は必要な情報を取りこむためのものです。最初に出力をリクエスト元のクライアントに送るための Java のクラスを取り込み、2番目に、入出力エラーを扱うための Java クラスを取り込んでいます。3、4番目は Java サーブレットのクラスを取り込んでいます。

import java.io.PrintWriter;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;


次に、サーブレット・クラスと doGet メソッドの宣言です。

public class Example_1 extends HttpServlet
{
   public void doGet(HttpServletRequest req,HttpServletResponse res)
   throws ServletException,IOException
   {


クライアントとしてブラウザーを想定しているため、次に出力のコンテント・タイプとしてHTML を指定します。そしてコンテンツをブラウザーに送るための PrintWriter オブジェクトを初期化します。

   res.setContentType(“text/html”);
   PrintWriter toBrowser = res.getWriter();


次の部分では、ブラウザーに HTML を送ります。

     toBrowser.println(“<HTML”);
     toBrowser.println(“<HEAD>");
     toBrowser.println("<TITLE>Example Servlet</TITLE>");
     toBrowser.println("</HEAD>”);
     toBrowser.println(“<BODY>”);
     toBrowser.println(“<H1>Servlet Example</H1>”);
     toBrowser.println(“<BR><HR><BR>”);
     toBrowser.print(“<H2>This was generated by the servlet”);
     toBrowser.println(“doGet method on a Domino server.</H2>”);
     toBrowser.println(“</BODY></HTML>”);

}

最後に、doPost メソッドで処理が完了します。

     public void doPost(HttpServletRequest req,
     HttpServletResponseres)
       throws ServletException, IOException
   {
     res.setContentType(“text/html”);
     PrintWriter toBrowser = res.getWriter();
     toBrowser.println(“<HTML”);
     toBrowser.println(“<HEAD>");
     toBrowser.print(“<TITLE>Example - Servlet</TITLE></HEAD>”);
     toBrowser.println(“</HEAD>");
     toBrowser.println(“<BODY>”);
     toBrowser.println(“<H1>Servlet Example</H1>”);
     toBrowser.println(“<BR><HR><BR>”);
     toBrowser.print(“<H2>This was generated by the servlet”);
     toBrowser.println(“doPost method on a Domino server.</H2>”);
     toBrowser.println(“</BODY></HTML>”);
   }
}


以下に Internet Explorer からサーブレットを呼び出した結果を示します。

Servlet results in a browser

そして、サーブレットが呼び出されたときにドミノ サーバーで起こったことを示します。クライアントのリクエストがサーバーに送られたときに Java サーブレット・マネージャーがロードされたことに注目してください。

Servlet results on a server

最後の行の "Addin: Agent printing: Example_1: init" は、サーブレットがサーバーのメモリー上にロードされたことを表しています。それ以降の各呼び出しでこのインスタンスが利用されます。これは、サーブレットに繰り返しリクエストを出すことで確認することができます。(ブラウザーをシャットダウンして再起動しても構いません)

サーブレットを変更する
サーブレットを変更する手続きは重要な点です。サーブレットのコードを変更して再コンパイルすれば、ドミノ サーバーはサーブレットをリロードしなければなりません。これは自動的に実行されるのではなく、HTTP タスクを再起動しなければなりません。以下の画面は HTTP サーバーを再起動した場面を示しています。サーブレットが破壊され、クライアントからのリクエストが到着するとリロードされる点に注目してください。

Restarting the server

サーバーの起動時にサーブレットをロードする
別の状況として、サーバーの起動時にサーブレットをロードするということができます。servlets.properties ファイルを変更して、ドミノ サーバーの起動時にサーブレットをロードすることができます。たとえば、名前が NotesNetTest であれば、プロパティー・ファイルは以下のようになるでしょう。

servlet.NotesNetTest.code = Example_1
servlets.startup = NotesNetTest


下の画面は起動時のドミノ サーバーのコンソールです。HTTP サーバーのタスクの前にサーブレットがロードされていることに注目してください。

Loading the servlet on the server startup

これで、NotesNetTest という名前を用いてサーブレットを呼び出すことができ、以下に示すような結果が得られます。

Calling the servlet using the new name
 
上に戻る
 
ドミノ・オブジェクトとの協調
サーブレットとドミノを緊密に統合することに焦点を当てましょう。次の例は、サーブレット中でドミノ・オブジェクトを用いており、ドミノ・ディレクトリーのエントリーにアクセスしています。

はじめに、プログラム・コードは先ほどの例と似通っていますが、lotus.domino.* で必要なドミノの Java クラスを取り込んでいる点が異なります。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import lotus.domino.*;
public class Example_2 extends HttpServlet {
   public void doGet(HttpServletRequest req, HttpServletResponse res)
       throws ServletException, IOException{
     res.setContentType("text/html");
     PrintWriter toBrowser = res.getWriter();
     toBrowser.println("<HTML");
     toBrowser.println("<HEAD>");
     toBrowser.println("<TITLE>Example 2</TITLE>");
     toBrowser.println("</HEAD>");
     toBrowser.println("<BODY>");
     toBrowser.println("<H1>Example 2</H1>");


ドミノ・オブジェクトの呼び出しは、try/catch ブロックで囲まれていなければなりません。そのため、次の行には try{ があります。このブロック内では、ドミノ・オブジェクトにアクセスするために NotesThread オブジェクトを作成しています。そして、新しく Session オブジェクトを作成します。Session オブジェクトにパラメーターを与えていないため、サーバーからアクセスされることになりますが、代わりに、ユーザーの名前やパスワードを指定します。次に、ドミノ・ディレクトリー (names.nsf) と People ビューにアクセスし、ビューの最初のドキュメントを呼び出します。

   try {
     NotesThread.sinitThread();
     Session s = NotesFactory.createSession();
     Database db = s.getDatabase("","names.nsf");
     View vw = db.getView("People");
     Document doc = vw.getFirstDocument();
     toBrowser.println(db.getTitle());
     toBrowser.println("<TABLE>");
     while (doc != null)
     {
       toBrowser.println("<TR><TD>");
       toBrowser.println(doc.getItemValueString("LastName"));
       toBrowser.println("</TD></TR>");
       doc = vw.getNextDocument(doc);
     }
     toBrowser.println("</TABLE>");
     vw.recycle();
     db.recycle();
     s.recycle();
   }
   catch (NotesException n) {


toBrowser の行では、データベースの名前をリクエスト元のクライアント (ブラウザー) に送信しています。while(doc!=null) は、ビューのすべての文書を調べるためのループで、ブラウザー内での各文書の LastName の値を表示し、ビューの次の文書を取得しています。最後の文書が終わると、ドミノ・オブジェクトで使用されていたメモリー領域をシステムに解放します。

最後に、発生したエラーを表示し、finally ブロックでは NotesThread オブジェクトを終了させます。

     System.out.println("Exception ID: " + n.id);
     System.out.println("Exception description: " + n.text);
   }
   finally
   {
     NotesThread.stermThread(); }
     toBrowser.println("</BODY></HTML>");
   }
}


下の画面では、テスト・サーバー上のサーブレットにアクセスした結果を示しています。

Accessing documents in the domino directory
 
上に戻る
 
ドミノ・フォームの結合
これまでにサーブレットの構築方法や、ドミノ・オブジェクトの組み込み方を見てきましたが、次はサーブレットとドミノ・フォームの結合について焦点を当てましょう。まずプログラム・コードを検討し、フォームを組み立てましょう。

以下のプログラム・コードはフォームから提出された値を扱うサーブレットです。値はフォームから取得し、ドミノ・データベース内の新しいエントリーを格納するために使用されます。プログラムはクラスやパッケージの取り込みという標準的な行から始まります。そして、フォームの FName や LName、Email、Phone フィールドから値を取得します。

import javax.servlet.*;
import javax.servlet.http.*;
import lotus.domino.*;
import java.io.PrintWriter;
import java.io.IOException;
public class Example_3 extends HttpServlet
{
   public void doGet(HttpServletRequest req, HttpServletResponse res)
     throws ServletException, IOException
   {
     res.setContentType("text/html");
     PrintWriter pw = res.getWriter();
     pw.println("<html>");
     pw.println("<head>");
     pw.println("<title>Example 3</title>");
     pw.println("</head>");
     pw.println("<body>");
     pw.println("<h1>Thank you!</h1>");
     String fname = req.getParameter("FName");
     String lname = req.getParameter("LName");
     String email = req.getParameter("Email");
     String phone = req.getParameter("Phone");


次に、先ほどのサーブレットで行ったように、NotesThread オブジェクトを作成し、ドミノ・オブジェクトと協調させるために Session オブジェクトを作成します。そして、ドミノ・ディレクトリーにアクセスします。この場合、データベースが見つかった場合のみ続行します。

   try
   {
     NotesThread.sinitThread();
     Session s = NotesFactory.createSession();
     Database db = s.getDatabase("","names.nsf");
     if (db != null)
     {


そして、新しい文書を作成し、文書にフォームの値を設定し、文書のフィールドを取得した値で初期化します。

   Document doc = db.createDocument();
   doc.replaceItemValue("Form", "Person");
   doc.replaceItemValue("FirstName", fname);
   doc.replaceItemValue("LastName", lname);
   doc.replaceItemValue("OfficePhoneNumber", phone);
   doc.replaceItemValue("MailAddress", email);


文書を保存し、文書やデータベース、Session オブジェクトで使用したシステム・リソースを解放します。(データベースが見つからない場合、Session オブジェクトが解放される前にエラー・メッセージが発生します)

       doc.save(true);
       doc.recycle();
       db.recycle();
     }
     else
     {
       pw.println("An error was encountered.");
     }
       s.recycle();
   }


最後に、ドミノに関連する例外を処理し、それからスレッドを終了してブラウザーにメッセージを表示します。

     catch (NotesException n)
     {
       pw.println("Notes Error: " + n.id);
       pw.println("Description: " + n.text);
     }
     catch (Exception e)
     {
       e.printStackTrace();
     }
     finally
     {
       NotesThread.stermThread();
     }
     pw.println(fname + " " + lname + " has been registered.");
     pw.println("</body></html>");
     }
}


サーブレット・プログラムの占める割合は、全体から見れば半分に過ぎません。次にドミノ・フォームの組み立てに注目しましょう。フォームはサーブレットに従わなければならず、サーブレットを指定して、新しく HTML フォームのタグを追加しなければなりません。これのようにして、フォームからサーブレットへの提出を行います。フォームの閉じるタグはこのタグの前に配置される必要があります。これはドミノによって作成されたフォームのタグです。以下にフォームのデザインを示します。

The form design

次にフォームの先頭に現れ、フォームをサーブレットにリダイレクトする HTML を示します。

[</form><form name="NotesNetExample" action="http://baseline2000:81/servlet/Example_3">]

大括弧 ([ and]) はテキストがパススルー HTML であることを表します。フォームの要素の名前属性はフォームに割り当てられます。この名前は JavaScript からフォームの要素にアクセスするときや、フォームをサーバーに提出するときに使用されます。提出され、アクションが送信されたときにアクション属性はシグナルを発生します。

次の画面は Internet Explorer でオープンされたフォームです。フォーム・データは提出時にサーブレットに送信されます。

The form design
 
上に戻る
 
まとめ
サーブレットとエージェントの選択は明確に決定できるものではありません。両者ともに Java をサポートしているため、言語は問題ではありません。それぞれに長所があり、またドミノが両者をサポートしているという点が重要です。どちらを選択するかという決定は開発者に委ねられます。拡張性のある Web の開発という点や WebSphere の強力なサーブレット・マネージャーを使用したいがためにサーブレットのほうを好むかもしれません。一方、経験豊富なドミノの開発者は堅牢なドミノ・エージェントの環境を好むでしょう。選択はあなたにかかっています。



著者について
アンソニー・パットンは、Java、XML、HTML 及びドミノのような、様々なテクノロジーを使って仕事をしています。彼は、「Practical LotusScript」 や 「Domino Development With Java」の著者で両者とも Manning Publications から手に入れられます。また、彼は熱烈なフィラデルフィア・スポーツのファンです。彼と連絡を取るには asp01@aye.net までメールをお送りください。
 
上に戻る