open intra-mart(6)−非同期通信

前回、DatabaseManagerクラスとしてDBアクセスに関するクラスを作成しましたが、このクラスを使うためには「load」関数を使って読み込まなければなりません。
Webアプリケーションなら基本的にはDBにアクセスするので使うソースを記述するたびに「load」関数を呼び出すのは面倒です。( ゚д゚ )

 

「OPEN intra-mart」には共通関数として特定の関数をいつでも呼べる状態にすることが出来る機能があります。それを使ってDatabaseManagerクラスを共通関数化しましょう。

DatabaseManagerの共通関数化

共通関数化するというのは、どういう事かといえば、サーバー起動時にその関数をサーバーのメモリ上においてそのままにしておくということです。
なので、使うたびに「load」関数で読み込む必要がなくなります。

 

共通関数化するにあたって方法は2種類あります。
XMLファイルによって定義する方法と「Procedure」関数を使って定義する方法です。

 

「Procedure」関数を使う方法は、いろいろ不都合な点があるので使いません。
XMLファイルよる定義で行います。

xml編集

XMLファイルによる共通関数の追加の方法については、公式ページに記載がありますので、詳しくはそちらを参照ください。

 

ここでは、DatabaseManagerクラスを共通関数化する方法の例としてXMLファイルの記述方法を示します。

▼WebContent/WEB-INF/classes/conf/jssp-config.xml

		<java-script-api>
			<!-- 省略 -->
			<api-script name="jssp/script/api/im_json#ImJson"/>
			<api-script name="lib/DatabaseManager#DatabaseManager"/>
		</java-script-api>

4行目の箇所がDatabaseManagerを共通関数化している箇所になります。

 

誰か、このXMLファイルで設定できることの詳細を教えてくれないかな〜。

共通関数の注意点

共通関数化する方法を示したわけですが、何点か注意点があります。

 

まず、XMLファイルによって共通関数化された関数は起動時に1回だけ読み込まれますので、サーバー起動中に、そのソースを変更したとしても反映されません。反映させるためにはサーバーを再起動させる必要があります。

 

開発する分には問題ないのですが、運用とかの場合で安易にサーバーを再起動できないようなときに困ります。まあ、運用環境などのソースを変更するときは基本的に再起動が必要なんですけどね。

 

次の注意点としては、共通関数化した関数のソースに存在するグローバル変数についてです。例えば以下のようなソースがあったとします。

▼ソースサンプル

var id = 0;
function getSample()
{
	return id;
}
function setSample( argId )
{
	id = argId;
}

この場合、以下のような問題が発生します。

  • サーバー起動直後にAさんが「getSample」関数を使っているページを開きました。「getSample」関数は0を返します。
  • Aさんが「setSample」で「id」変数に5を代入するページを開きました。
  • Bさんが「getSample」関数を使っているページを開きました。「getSample」関数は5を返します。

 

つまり、共通関数化されたソースの中にあるグローバル変数もサーバーのメモリ上に乗っかり、サーバーでひとつのものとなります。
この挙動がおかしいというわけではなく、上記の「Bさん」の場合でも0が取得されるだろうと勘違いしやすいので注意が必要ということです。

非同期通信を使ってみよう

話はガラリと変わって、非同期通信を使ってみたいと思います。

 

まあ、流行りですし、なにより、<IMART type="string">タグで文字列を表示したり、<IMART type="condition">タグで画面を制御したり、<IMART type="input">タグでフォームパーツを作りたくないんです。

 

それが、なぜ非同期通信に関係するかといいますと、画面上に表示するデータを非同期通信を使って取得し、それをクライアントサイドのJavascriptで表示・制御すれば<IMART>タグを使わなくて済むからです。

 

あとあと、なぜ<IMART>タグを使いたくないかというと、htmlファイルのソースが見づらくなるからです。
あと、<IMART type="input">タグによって生成されたタグのタグ名が大文字になりますし、なにより「style」属性が<IMART type="input">タグの独自属性として存在するため、本来の「style」属性が使用出来ません。

 

まあ、色々あるわけですよ。

<IMART type="jsspRpc"> タグ

タグの詳細は「OPEN intra-mart」のAPIを参照してください。

 

今回は、前回作成したDBアクセスのソースを非同期通信を使ったものに変更します。

▼WebContent/pages/src/test/rpc_database/rpc_database.html

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<meta http-equiv="Content-Style-Type" content="text/css" />

<imart type="jsspRpc" name="server" page="test/rpc_database/server_side_logic/managePersonData" callback="callbackServer"></imart>

<!-- スクリプト -->
<script type="text/javascript" src="/oimart/csjs/jquery/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="/oimart/csjs/jquery-ui-1.8.19.custom/js/jquery-ui-1.8.19.custom.min.js"></script>
<script type="text/javascript" src="/oimart/csjs/jquery.jqGrid-4.3.2/js/jquery.jqGrid.min.js"></script>
<script type="text/javascript" src="/oimart/csjs/jquery.jqGrid-4.3.2/js/i18n/grid.locale-ja.js"></script>
<script type="text/javascript" src="/oimart/csjs/pages/src/test/rpc_database/rpc_database.js"></script>
<!-- スタイルシート -->
<link rel="stylesheet" href="/oimart/csjs/jquery.jqGrid-4.3.2/css/ui.jqgrid.css" type="text/css" />
<link rel="stylesheet" href="/oimart/csjs/jquery-ui-1.8.19.custom/css/cupertino/jquery-ui-1.8.19.custom.css" type="text/css" />
<title>DB取得非同期通信</title>
</head>
<body>
	<div id="divTable">
	</div>
</body>
</html>

<IMART type="jsspRpc">タグの「page」属性に非同期通信の対象となるサーバーサイドJavascript(SSJS)のソースパスを指定します。指定したソース内に存在する関数はクライアントサイドJavascript(CSJS)から呼ぶことが可能な状態になります。因みに、SSJS上で「load」関数を使っていた場合、読み込まれたソースの関数もCSJSから呼ぶことが可能になります。
(セキュリティ的にどうなんでしょうね。。)

 

name」属性にはSSJSの関数が包括されるオブジェクト名を指定します。つまり、今回の場合だと「server」というオブジェクトのプロパティにSSJSの関数が含まれます。

 

callback」属性にはSSJSの処理結果を受け取るCSJSの関数名を指定します。

サーバーサイドJavascript

SSJSではデータを取得する関数を作成します。

▼WebContent/pages/src/test/rpc_database/server_side_logic/managePersonData.js

/**
 * @fileoverview	PersonDBアクセス
 */

/**
 * Personデータ取得関数
 *
 * @returns {Array} DB検索結果データ
 */
function getPersonData() {
	var databaseManager = new DatabaseManager(true);
	var rows;
	var data = [];
	/**
	 *
	 * @param {IfRubbishDatabase}
	 *            dbh
	 */
	function handler(dbh) {
		rows = dbh.selectBy("PERSON","birth < ?",DatabaseManager.changeParams([new Date()]));
		data = DatabaseManager.changeData(rows);
	}
	try {
		databaseManager.connect(handler);
	} catch (e) {
		// データベースエラー
		var logger = Logger.getLogger();
		logger.info(ImJson.toJSONString(e));
		ImAjaxUtil.setErrorResponseHeaders( "IM-JSSP-00002" );
	}

	return data;
}

データを取得する部分ですが、実はDatabaseManagerを前回から変更しまして、クラス内でtry-catchしないようにしました。なので、DB接続する際にはその処理をtry-catchで囲む必要があります。

 

基本的には前回と同じなので説明は省略しますが、Exceptionをキャッチしている部分について少し説明を加えます。

 

27行​目:ロガーを作成しています。デフォルトのロガーが作成されますので、コンソールログになります。

 

28行目:ログを出力しています。ログレベルはinfoです。ログレベルやログに関する詳細については「OPEN intra-mart」のAPIや「製品版 intra-mart」のログ設定ガイドに記載があります。

 

29行目:非同期通信時にエラーが発生したことを示しています。「ImAjaxUtil.setErrorResponseHeaders」関数への引数にはエラーコードを指定しています。
エラーコードとは「WebContent/WEB-INF/classes/conf/jssp-error-message_ja.properties」のプロパティファイルで定義されているメッセージコードになります。
プロパティファイルには任意にメッセージを追加できます。
IM-JSSP-00002=データベースエラーが発生しました。」と追加で定義しています。

 

32行目:returnでDB取得値を返しています。ここで返した値がcallback関数への引数となります。

クライアントサイドJavascript

CSJSではSSJSの関数を呼び出す処理とそのコールバック関数を実装します。

 

今回は、画面表示時にDBのデータを取得し、それを一覧表で表示します。
私はCSJSでのDOM操作にjQueryしか使えないので、jQueryとそのプラグインのjQueryUI、jqGridを使っています。

▼WebContent/csjs/pages/src/test/rpc_database/rpc_database.js

/**
 * @fileoverview DBアクセス確認用のCSJS
 */

jQuery(function() {
	server.getPersonData();
});

/**
 * サーバーロジックコールバック関数
 *
 * @param {Object}
 *            result
 */
function callbackServer(result) {
	// jqGrid用のテーブルタグ作成
	var table = jQuery("<table>").attr({
		"id" : "tableGrid"
	});
	jQuery("#divTable").append(table).css({
		"font-size" : "62.5%"
	});

	/**
	 * date型のソート用
	 *
	 * @param {Object}
	 *            cell cellオブジェクト
	 * @return {Number} Date型のgetTime()の値
	 */
	function sortTypeDate(cell) {
		if (isDate(cell)) {
			return cell.getTime();
		} else {
			return 0;
		}
	}

	// jqGrid化
	jQuery("#tableGrid").jqGrid({
		"data" : result,
		"datatype" : "clientSide",
		"colNames" : [ "ID", "名前", "年齢", "生年月日", "住所" ],
		"colModel" : [ {
			"name" : "id",
			"index" : "id",
			"width" : 90
		}, {
			"name" : "name",
			"index" : "name",
			"width" : 100
		}, {
			"name" : "age",
			"index" : "age",
			"width" : 100
		}, {
			"name" : "birth",
			"index" : "birth",
			"width" : 100,
			"formatter" : "date",
			"formatoptions" : {
				"newformat" : "Y/m/d"
			},
			"sorttype" : sortTypeDate
		}, {
			"name" : "adress",
			"index" : "adress",
			"width" : 200
		} ],
		"caption" : "PERSONテーブル"
	});

}
/**
 * Date型か判定
 * @param {Object}	d	判定対象オブジェクト
 * @returns {Boolean}	Date型か判定
 */
function isDate(d) {
	var TYPE_DATE = "[object date]";
	return Object.prototype.toString.call(d).toLowerCase() === TYPE_DATE;
}

CSJSは外出ししています。XHTMLなので。ライブラリ以外の各ページごとのCSJSはファイルが散らからないようにSSJSと同じフォルダ構造にして配置しています。

 

解説です。

6行目:画面表示のタイミングでSSJSの関数を呼び出しています。<IMART type="jsspRpc">タグの「name」属性で指定した「server」というオブジェクトの「getPersonData」関数を呼び出すことによって、SSJSの同名の関数を呼び出すことができます。

 

15行目:コールバック関数です。引数にはDBの取得値が入ります。
あっ!今更ですが、DBの取得値はJavascriptのObjectの配列でObjectのプロパティにはカラム名の小文字で値が格納されています。

 

16〜72行目:DB取得値をjqGridを使って表示しています。
jqGridってなんぞやというのは、その説明だけでも結構時間がかかりそうですし、私自身そこまで詳しくないので割愛させて頂きます。

 

このような感じに、簡単に非同期通信によってSSJSより値をCSJSに受け渡すことができます。その受け取ったデータによって自分の好きなようにCSJSで画面を構築してもいいわけです。
IE8以前とかだとCSJSが遅いのでアレですが、私はIEが嫌いなのでそこはスルーします。IEだけ他と違う挙動をするからといって、そこにリソースを割きたくないのです。

ログについて

今回、ログを出力している部分がありますが、そこについて少し解説を加えます。

 

まず、「OPEN intra-mart」はログ出力にLogBackを使っているとかどうとか。そんなの知らないので、こうしたらこう動いたという例だけ示します。

▼WebContent/WEB-INF/classes/logback.xml

<configuration>
	<jmxConfigurator/>

	<appender name="STDOUT"
		class="ch.qos.logback.core.ConsoleAppender">
		<layout class="ch.qos.logback.classic.PatternLayout">
			<!-- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> -->
			<pattern>[%d{HH:mm:ss.SSS}] [%level] %logger{10} - %msg%n</pattern>
		</layout>
	</appender>
	<appender name="DB_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>C:/oim/log/platform/database.log</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<FileNamePattern>
				C:/oim/log/platform/database-%d{yyyy-MM}.zip
			</FileNamePattern>
		</rollingPolicy>
		<layout class="ch.qos.logback.classic.PatternLayout">
			<!-- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> -->
			<pattern>[%d{HH:mm:ss.SSS}] [%level] %logger{10} - %msg%n</pattern>
		</layout>
	</appender>
	<root>
		<level value="info" />
		<appender-ref ref="STDOUT" />
	</root>

	<logger name="sample.script.jsunit">
		<level value="debug" />
	</logger>
	<logger name="DB_LOG">
		<level value="info" />
		<appender-ref ref="DB_LOG_FILE" />
	</logger>
</configuration>

 

11〜22行目:DBログとして新規に追加したログの定義情報です。

 

11行目:DB_LOG_FILE」という名前で、ファイルにメッセージを出力するタイプで、指定のタイミングでローテイトされる(過去ファイルが作成される)ログを定義しています。

 

12行目:ログのファイルパスとそのファイル名を指定しています。

 

13〜17行目:日時によってローテイトする条件を定義しています。「C:/oim/log/platform/database-%d{yyyy-MM}.zip」この部分がそのまま、ローテイトされる過去分のログファイルの扱い方になります。「C:/oim/log/platform/」の場所に「database-2012-05」というようなファイル名で、月毎にローテイトされて、更にそのファイルはZIPで圧縮されます。

 

つまりは、月が変わって初めてログが出力されるタイミングで、いままであった「database.log」が「database-2012-05.zip」といったzipファイルに変わるということです。そして、今後のログは新規に「database.log」に出力されます。

 

31〜34行目:ここでログの出力定義をしています。Loggerの名前は「DB_LOG」です。
つまりは、<appender>タグで囲まれた部分でログのタイプを定義して、実際に出力するログの定義は<logger>タグで定義しており、このログが指定された場合「DB_LOG_FILE」のログが出力されるようにしています。

 

configuration/logger/levelタグで出力するログのレベルを定義しています。今回はinfoレベルで定義しているのでinfoレベル以上のログがファイルに出力されます。

 

で、どうやってこのログを出力するのかですが、Loggerを取得する際に、ここで定義したLoggerの名前を指定するだけです。

▼サンプル

		var logger = Logger.getLogger( "DB_LOG" );
		logger.info(ImJson.toJSONString(e));

 

以上です。

 

ソース一式

あっ!そうそう、非同期通信する際に、JSON文字列をObjectに変換する「ImJson」というのが使われているのですが、これに不具合があって1970/1/1以前の日付データを変換できません。修正したものをソース一式に入れています。
「WebContent/pages/src/jssp/script/api/im_json.js」「WebContent/csjs/im_json.js」の2ファイルです。

次回予告

これでひと通り、サンプルソースで溜め込んでいたものは終了です。
次は何にしようかな、Javascriptのパッケージ化あたりにしようかな〜。

次回はサクラにドッキドキ!

 

open intra-mart(5)−DBアクセスを改善する

さてさて、前回ようやくDBにアクセスできてWebアプリケーションぽくなり始めましたが、このままでは使いにくいのでラッピングしちゃいましょう。

 

具体的にどこが使いにくいかというと、

  • DBに接続するたびに接続URLとか指定したくない
  • DBの取得値がjavascriptのオブジェクトではなくJAVAのオブジェクトなので使いづらい
  • できる限り、JAVAのAPIをコードの中に書きたくない
  • eclipseのコード補完が使えない

などがあります。

あと、「氷菓」が面白いですね。

 

DBアクセスライブラリ化計画

DBにアクセスする関係の処理をライブラリ化(クラス化)してしまいます。javascriptのクラスとかわからないという方はこちらを参照してください。

クラス化しよう

javascriptでクラスを作るといっても正確にはクラスではありません。まあ、そこら辺はややこしいのでクラスと呼ぶことにします。

「DatabaseManager」という名前でクラス化します。このクラスを使うことによってDBアクセスの一通りができるようにします。

▼クラス「DatabaseManager」の雛形(WebContent/pages/src/lib/DatabaseManager.js)

/**
 * データベースマネージャー
 *
 * @class DatabaseManager
 * @constructor
 */
var DatabaseManager = function(logging) {
	this.init(logging);
};
(function() {
	importPackage(Packages.rubbish.db);
	importPackage(Packages.rubbish.db.rhino);
	JsArrayExtension.extend();

	/**
	 * Packages.rubbish.db.RubbishDatabase
	 *
	 * @type IfRubbishDatabase
	 */
	var dbh = null;

	// プロトタイプセット
	DatabaseManager.prototype = {
		constructor : DatabaseManager,
		/**
		 * 初期化処理
		 *
		 * @protected
		 * @param {Boolean}
		 *            logging ログフラグ
		 */
		init : function(logging) {
			dbh = new RubbishDatabase();
			// ログ設定
			logging = logging === true;
			dbh.logging = logging;
		}
	};
})();

コンストラクタと初期化処理があるだけの単純なクラスです。

 

32行目からのinitメソッドが初期化処理になります。中ではRubbishDatabaseをインスタンス化しています。
このinitメソッドをコンストラクタの8行目で呼んでいます。引数はログを出力するかのフラグです。

 

DB接続メソッドの作成

「DatabaseManager」の雛形クラスにDBへの接続メソッドを追加します。前回のソースでDBに接続していた部分をメソッド化しています。

▼クラス「DatabaseManager」に「connect」メソッドを追加

/**
 * データベースマネージャー
 *
 * @class DatabaseManager
 * @constructor
 */
var DatabaseManager = function(logging) {
	this.init(logging);
};
(function() {

	// 省略

	/**
	 * データベースURL
	 *
	 * @constant
	 * @type String
	 */
	var DB_URL = "jdbc:mysql://lubuntumysql:3306/oimart";
	/**
	 * データベースユーザ
	 *
	 * @constant
	 * @type String
	 */
	var DB_USER = "root";
	/**
	 * データベースパスワード
	 *
	 * @constant
	 * @type String
	 */
	var DB_PASS = "mysql";

	// プロトタイプセット
	DatabaseManager.prototype = {

		// 省略

		/**
		 * データベース接続
		 *
		 * @param {Function}
		 *            handler ハンドラー:引数にrubbish.db.RubbishDatabaseのインスタンスを受け取る
		 * @return {Object}
		 */
		connect : function(handler) {
			var result = {
				"error" : false,
				"errorMessage" : null
			};

			try {
				// ハンドラーが存在する場合
				if (isFunction(handler)) {
					dbh.connect(DB_URL, DB_USER, DB_PASS, handler);
				} else {
					// ハンドラーがない場合
					dbh.connect(DB_URL, DB_USER, DB_PASS);
				}
			} catch (e) {
				result.error = true;
				result.errorMessage = e.message + "";
			}
			return result;
		}
	};
})();

問題点であった、DBに接続するたびに接続URLを指定しないといけない部分をここで吸収します。

 

48行目からがDB接続のメソッドになります。接続URLなどはクラスのプライベートメンバに定義しています。
また、この関数ではDB接続時に処理を行う関数を指定する場合と指定しない場合で処理を切り分けています。理由としては、ハンドラーが指定できる場合もあれば、指定できない場合もあり、また、javascriptはJAVAと違い、引数の違いによって別の関数とは判断してくれないため、中で処理を切り分けています。

 

54行目でDB接続処理をtry-catchで囲んでいますが、これはDBアクセスによるエラーを判定するためです。ハンドラー内で発生したExceptionもここでキャッチされます。
※javascriptではtry-catchが遅い気がするのであまり使いたくはないですけど。

 

このメソッドですが、最終的には接続URLなどはXMLファイルで外出ししておいて、そこから読み取って接続するように変更したり、引数でどの接続情報を使用するかを決めれるようにする必要があります。

DB切断メソッドの作成

DB接続時にハンドラーを引数に指定している場合は自動的に切断されるので必要無いですが、それ以外の場合は明示的に切断する必要があるので切断メソッドを追加します。

▼クラス「DatabaseManager」に「disconnect」メソッドを追加

		/**
		 * データベース切断
		 *
		 * @returns {Object}
		 */
		disconnect : function() {
			var result = {
				"error" : false,
				"errorMessage" : null
			};

			try {
				dbh.disconnect();
			} catch (e) {
				result.error = true;
				result.errorMessage = e.message + "";
			}

			return result;
		}

ここでは、RubbishDatabaseのdisconnectメソッドを呼んで終わりです。

DB検索メソッドの作成

DB接続時にハンドラーを指定する場合は必要ないのですが、それ以外の場合で簡単にデータが取得できるようにラッパー関数を作成します。(正直無くてもいいですが、その場合はプライベートメンバとして持っている、RubbishDatabaseのインスタンスを公開するか、取得できるようにする必要があります。)

▼クラス「DatabaseManager」に「select」メソッドを追加

		/**
		 * 検索実行
		 *
		 * @param {String}
		 *            sql SQL文字列
		 * @param {Object[]}
		 *            [params] 置換パラメータ
		 * @returns {Object}
		 */
		select : function(sql, params) {
			var result = {
				"error" : false,
				"errorMessage" : null,
				"data" : null
			};
			try {
				switch (arguments.length) {
				case 1:
					// 置換パラメータなし
					result.data = dbh.query(sql);
					break;
				case 2:
					// 置換パラメータあり
					result.data = selectWithParam(sql, params);
					break;
				default:
					break;
				}
			} catch (e) {
				result.error = true;
				result.errorMessage = e.message + "";
			}

			return result;
		},

		/**
		 * パラメータ置換検索処理
		 *
		 * @protected
		 * @param {String}
		 *            sql SQL文字列
		 * @param {Object[]}
		 *            params 置換パラメータ
		 * @type Object[]
		 * @returns {Object[]} 検索データ
		 */
		selectWithParam : function(sql, params) {
			return dbh.query( sql, params );
		}

このメソッドは引数にSQL文と置換パラメータを受け取ります。
メソッド内部では置換パラメータを指定する場合と指定しない場合で処理を切り分けていますが、最終的にはRubbishDatabaseのqueryメソッドを呼んでいます。
置換パラメータを指定する場合に呼んでいるselectWithParamメソッドを作った理由は後で説明します。

 

このメソッドへの引数であるSQL文には単純に「SELECT * FROM PERSON ORDER BY id」などのそのままのSQL文を指定します。

 

第2引数である置換パラメータがどのようなものかというと、SQL文「SELECT * FROM PERSON WHERE id = ? AND age = ?」があった場合、置換パラメータの配列に「"1001"」「24」を入れるとそれぞれが「?」の部分に代入されて以下のようなSQL文に変換されて実行されます。

「SELECT * FROM PERSON WHERE id = '1001' AND age = 24」

DB検索パラメータ変換メソッド(静的メソッド)作成

さて、DBを取得するためのメソッドは作成しましたが、ここで問題があります。

置換パラメータで文字列や数値は指定できますが日付型はうまく指定できません。理由は指定している日付型が悪魔でもjavascriptの日付型であり、JAVAの日付型ではないためです。

 

そこで、置換パラメータの内、日付型の要素のみJAVAの日付型に変換するメソッドをクラス「DatabaseManager」の静的メソッドとして追加します。

▼クラス「DatabaseManager」に静的メソッド「changeParams」を追加する

/**
 * DB置換パラメータをJAVAの型に変換
 * @param {Array}	params
 * @return {Array}	型変換後のパラメータ配列
 */
DatabaseManager.changeParams = function(params)
{
	var i,len;
	var params2 = new Array();
	for( i = 0,len = params.length; i < len; i++ )
	{
		params2[i] = params[i];
		if ( isDate( params2[i] ) )
		{
			params2[i] = java.util.Date( params2[i].getTime() );
		}
	}
	return params2;
};

置換パラメータの配列をグルグル回して日付型があったらJAVAの日付型に変換しています。

 

他の文字列や数値もjavascriptのオブジェクトなのですが、なんかうまく動いているので放っておきます。うまく動かないものが発見されたら追加します。

 

selectWithParamメソッドを作ったのは、内部でこの静的メソッドを呼ぶためです。

▼クラス「DatabaseManager」の「selectWithParam」メソッドを変更

		/**
		 * パラメータ置換検索処理
		 *
		 * @protected
		 * @param {String}
		 *            sql SQL文字列
		 * @param {Object[]}
		 *            params 置換パラメータ
		 * @type Object[]
		 * @returns {Object[]} 検索データ
		 */
		selectWithParam : function(sql, params) {
			return dbh.query( sql, DatabaseManager.changeParams( params ) );
		}

これで、置換パラメータに日付型を指定しても問題なく検索が実行されます。

このメソッドはjsdocと呼ばれるコメントの記述方法によってprotectedメソッドとしています。eclipseは空気を読んでこのメソッドを入力補完の候補に出さないようにしてくれますが、実際は呼べるので紳士協定として呼ばないようにしてください。

DB取得値変換メソッド(静的メソッド)作成

DBを検索して値を取得していますが、呼んでいるのはJAVAのAPIのため取得できる値もJAVAのオブジェクトのままです。(具体的にはMapの配列のはずです。)

ここでは、その取得値をjavascriptのObject配列に変換するメソッドを静的メソッドとして作成します。

▼クラス「DatabaseManager」に静的メソッド「changeData」を追加する

/**
 * DB取得値をjavascriptオブジェクトに変換
 * @param {Array} rows	DB検索結果データ
 * @return {Array} DB検索結果をjavascriptオブジェクトに変換
 */
DatabaseManager.changeData = function( rows )
{
	var item = "";
	var i = 0;
	var len = 0;
	var row;
	var data = new Array();
	for( i = 0,len = rows.length; i < len; i++ ){
		row = rows[i];
		data[i] = new Object();
		for ( item in row )
		{
			item = ("" + item).toLowerCase();
			data[i][item] = row[item];
			if( isDate( data[i][item] ) )
			{
				data[i][item] = new Date(data[i][item].getTime());
			}
		}
	}
	return data;
};

これも、「selectWithParam」メソッドと同様に日付型のデータのみjavascriptの日付型に変換しています。

 

他のデータについても変換する必要があるかもしれませんが、それはその時です。

 

「select」メソッドの取得値もこのメソッドで変換してから値を返すように変更します。

▼クラス「DatabaseManager」の「select」メソッドを変更

		/**
		 * 検索実行
		 *
		 * @param {String}
		 *            sql SQL文字列
		 * @param {Object[]}
		 *            [params] 置換パラメータ
		 * @returns {Object}
		 */
		select : function(sql, params) {
			var result = {
				"error" : false,
				"errorMessage" : null,
				"data" : null
			};
			try {
				switch (arguments.length) {
				case 1:
					// 置換パラメータなし
					result.data = DatabaseManager.changeData( dbh.query(sql) );
					break;
				case 2:
					// 置換パラメータあり
					result.data = DatabaseManager.changeData( selectWithParam(sql, params) );
					break;
				default:
					break;
				}
			} catch (e) {
				result.error = true;
				result.errorMessage = e.message + "";
			}

			return result;
		}

これで、一通りのメソッドは作成しました。

+αで使いやすくしよう

「DatabaseManager」クラスを作成しましたが、eclipseの入力補完に関連してもう少しだけ使いやすくするために、2つのクラスを作成します。

DBアクセス結果クラス作成

「DatabaseManager」クラスの「connect」メソッドや「select」メソッドの返却値は以下のプロパティを持つオブジェクトです。

  • {Boolean} error エラーフラグ
  • {String} errorMessage エラーメッセージ
  • {Object} data データベース取得値など

 

オブジェクトのままでも、まあまあ問題ないわけですが、やはり返却値などのインターフェースとなる部分はある程度きっちりしておきたいのでクラス化します。

 

大したことしてないので、下においてあるソースを参照してください。

eclipseの入力補完用にRubbishDatabaseのインターフェースを作成

DB接続時にハンドラーを指定する場合、引数で渡ってくる「RubbishDatabase」のインスタンスを使うわけですが、JAVAのインスタンスなのでもちろんコード補完はしてくれません。

 

そこで、IFとしてクラスを作成します。ただ、コード補完のためだけのものなので、実際に呼び出しても何もしてくれません。
また、全網羅しているわけではないので必要に応じて追加してください。
 

これも、大したことしていませんのでソースを参照してください。

 

完成したソース

DBアクセスライブラリを使ってデータ取得&表示

さあさあ、つくったライブラリを使ってデータを取得し、表示しましょう。

データを取得しよう

PERSONテーブルのレコードを条件付きで取得します。

▼WebContent/pages/src/test/database/database.js

/**
 * @fileoverview	DBアクセス確認用
 */
/**
 * 画面表示オブジェクト
 *
 * @type Object
 */
var $objDisp = null;
load("lib/DatabaseManager");

/**
 * 画面表示初期処理
 *
 * @author
 */
function init() {
	try {
		var data = getPersonData();
	} catch (e) {
		Debug.browse(e);
	}
	$objDisp = {
		"data" : data
	};
}

/**
 * Personデータ取得関数
 * @return {Array}	DB検索結果データ
 * @throws {Exception}
 */
function getPersonData()
{
	var databaseManager = new DatabaseManager(true);
	var rows;
	var data = [];
	/**
	 *
	 * @param {IfRubbishDatabase}	dbh
	 */
	function handler(dbh)
	{
		rows = dbh.selectBy("PERSON","birth <= ?",DatabaseManager.changeParams([new Date(1987,1,7,12,12,11)]));
		data = DatabaseManager.changeData(rows);
	}
	var result = databaseManager.connect(handler);
	if ( result.getError() )
	{
		throw new Error( result.getErrorMessage() );
	}
	return data;
}

解説です。

10行目:作成した「DatabaseManager」クラスが利用できるように「load」関数で読み込んでいます。詳細は「OPEN intra-mart」のAPIを参照してください。

 

19行目:データを取得しています。

 

35行目:「DatabaseManager」クラスをインスタンス化しています。

 

42行目:DB接続時に行う処理の関数です。40行目に着目してください。「@param {IfRubbishDatabase} dbh」と記述することによって引数はIfRubbishDatabase型と判断してくれます。

この「IfRubbishDatabase」は先ほど作成したコード補完用のクラスです。これで、「selectBy」などをコード補完で入力できます。

 

44〜45行目:実際にデータを取得している部分になります。作成した静的メソッドによって型変換をしています。

 

47〜51行目:DBに接続しています。エラーが発生した場合はErrorをthrowするようにしてみました。

 

23〜25行目:取得したデータを画面上に表示できるようにグローバル変数に設定しています。

 

以上です。

データを表示しよう

取得したデータをTABLEタグの一覧で表示します。

▼WebContent/pages/src/test/database/database.html

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<style type="text/css">
table {border:solid 1px #aaaaff;border-collapse: collapse;}
td,th {border:solid 1px #aaaaff;padding: 5px;}
th {background-color: #ddddff;color:#555599}
</style>
<title>DBアクセス</title>
</head>
<body>
	<div id="divTable">
		<table>
			<caption>PERSONテーブル</caption>
			<tr>
				<th>ID</th>
				<th>名前</th>
				<th>年齢</th>
				<th>生年月日</th>
				<th>住所</th>
			</tr>
			<imart type="repeat" list=$objDisp.data item="item">
			<tr>
				<td><imart type="string" value=item.id ></imart></td>
				<td><imart type="string" value=item.name ></imart></td>
				<td><imart type="string" value=item.age ></imart></td>
				<td><imart type="date" value=item.birth format="yyyy/MM/dd"></imart></td>
				<td><imart type="string" value=item.adress ></imart></td>
			</tr>
			</imart>
		</table>
	</div>
</body>
</html>

解説です。

 

26行目:imartタグの「repeat」を利用して、配列の内容を表示しています。取得したデータの数だけimartタグで囲まれた27〜33行目が繰り返して表示されます。詳細は「OPEN intra-mart」のAPIを参照してください。

 

31行目:imartタグの「date」を利用しています。日付型の変数を指定のフォーマットで表示できます。詳細は「OPEN intra-mart」のAPIを参照してください。

 

以上です。

 

ソース一式

次回予告

えーと何て言うか。。
そのー、imartタグをあまり使いたくないんです。
わかりにくいんです。HTMLの生成なんてクライアントのjavascriptでしちゃえばいいじゃないですか!

次回、あれとそれとこれの3本です。

open intra-mart(4)−DBアクセス

さてさて、またもや前回から1ヶ月程度たってしまいました。

まあ、いいか。

今回は、「OPEN intra-mart JSSP」でDBアクセスを実行してみたいと思います。

DBアクセスといってもselectするだけですが。insertやupdateについては、また別の機会にということで。

 

取得するデータを用意しよう

open intra-mart(2)−開発環境を整える」の記事で「MySQL」を入れてもらったと思いますが、このDBに取得するためのテーブルを作成し、レコードを追加します。

「MySQL」にデータベースを作成する

「MyWebSQL」を使ってデータベース「oimart」を作成してください。

▼データベース”oimart”作成

データベース作成

 

データベース”oimart”にテーブルを作成する。

「MyWebSQL」から以下のSQLを実行してテーブルの作成、および、レコードの追加を行なってください。

▼PERSONテーブル

--table structure for PERSON
CREATE TABLE PERSON (
  id varchar(100) NOT NULL DEFAULT '',
  name varchar(500) DEFAULT NULL,
  age int(5) DEFAULT NULL,
  birth datetime DEFAULT NULL,
  adress varchar(1000) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--data for table PERSON
insert into PERSON values ("1001","山田太郎",24,"1987-02-07 12:12:12","兵庫県神戸市");
insert into PERSON values ("1002","佐倉綾音",23,"1988-08-23 00:00:00","東京都品川区");
insert into PERSON values ("1003","山口眞弓",26,"1985-07-01 00:00:00","富山県富山市");
insert into PERSON values ("1004","浅沼晋太郎",38,"1974-09-28 20:20:20","京都府舞鶴市");
insert into PERSON values ("1005","日笠陽子",48,"1963-10-23 23:59:59","岡山県");
insert into PERSON values ("1006","丹下桜",31,"1980-07-29 05:08:08","茨城県");

eclipseを使って外部から「MySQL」にアクセスできるか確認しよう

「MyWebSQL」を使って、仮想マシン上の「MySQL」にホストマシンからアクセスしていますが、実は、デフォルトのままだと「MySQL」にホストマシンなどの外部マシンからアクセス出来ません。

 

「MyWebSQL」は仮想マシン上のPHPが仮想マシン上の「MySQL」にアクセスしているからホストマシンからでもPHPを経由して「MySQL」にアクセスできています。

 

ではでは、まず、eclipseを使って「MySQL」に接続して、できないことを確認しましょう。

 

eclipseを起動してパースペクティブ「DBViewer」を開いてください。

▼パースペクティブ「DBViewer」

パースペクティブDBViewer

 

DBツリービューから「DBViewerPlugin」を右クリック>「登録」で新規に接続設定を作成してください。

▼新規に接続設定を作成

データベース接続定義_新規作成

 

接続設定を行います。

JDBCに「MySQL」のJDBCを選択してください。JDBCがない場合は「http://dev.mysql.com/downloads/connector/j/」より「MySQL」と同じバージョンのものをダウンロードしてください。ダウンロードしたらjarファイルをeclipseのプロジェクトの「WebContent/WEB-INF/lib」にコピーしてください。

 

接続文字列には「jdbc:mysql://仮想マシンのマシン名またはIP:3306/oimart?useUnicode=true&characterEncoding=UTF8」を指定してください。

 

接続ユーザには「root」を、接続パスワードには「MySQL」のインストール時に指定したパスワードを入力してください。

▼JDBC指定

データベース接続定義_JDBC

▼接続情報

データベース接続定義_接続定義

 

テスト接続を実行

▼接続に失敗します。

データベース接続エラー

 

ユーザ情報を変更しよう

「MySQL」への接続ユーザである「root」には現在、仮想マシン上からのアクセスのみが許可されています。

 

そこで、ホストマシンからのアクセスを許可するように変更します。
まず、「MyWebSQL」の画面を開いてください。この画面からユーザの情報を変更します。
次に、画面上部にあるメニュー>ツール>ユーザーマネージャを開いてください。

 

ユーザーの追加ボタンを押して新規にユーザを追加し、以下の設定を行なってください

  • User Name:root
  • ホスト:ホストマシンのIP
    (※ここでホストマシンのIPを指定するわけですが、DHCPなどだとIPが変わる可能性があるためワイルドカードである「%」を使うことを推めます。また、ホストマシンと仮想マシンが接続するときにどのIPが利用されているのかにも注意してください。)

 

以上で設定は終了です。ユーザの追加ボタンを押してダイアログを閉じてください。

▼ユーザ設定情報

DBユーザ追加

 

再度eclipseから「MySQL」にアクセスできるか確認しよう

先程と同様にしてeclipseから「MySQL」にアクセスできるか確認してください。

 

▼接続が成功しました。

データベース接続成功

※接続が成功しない場合は、先ほど追加したユーザにグローバル権限などを設定する必要があるかもしれません。

 

「OPEN intra-mart」からDBにアクセスしよう

長々と下準備を書いてきましたが、ここからが本題です。

「OPEN intra-mart JSSP」から「MySQL」にアクセスしてレコードを取得します。

 

しかし、ここで問題が。。。なんとっ!標準でDBアクセスAPIが存在しません。公式ページを見てみると作成する予定にはなっていますが、それは2年前とかの状態で停滞しています。というより全体的に停滞しているんですよね。結構、使いやすいと思うんですけど。。。

 

で、DBアクセスAPIがないわけですが、「OPEN intra-mart JSSP」の元となっている「Rhino」の機能としてJAVAのAPIを呼べるので、単純に「OPEN intra-mart JSSP」からJAVAのAPIを使ってDBにアクセスしてしまえば問題ありません。

 

今回使うJAVAのAPIは「rubbish-db」です。ライブラリをリンク先よりダウンロードしてプロジェクトの「WebContent/WEB-INF/lib」にコピーしてください。

 

これを選んだ理由は「Rhino」から使われることを考慮されているような節があったからです。(その程度の理由なので、JAVAのAPIで使い慣れているものがあるのでしたら、そちらを使ってDBアクセスを行なっていただいて問題ありません。)

 

「OPEN intra-mart」からJAVAのAPIを呼んでみよう

「OPEN intra-mart」からJAVAのAPIを使うためのキーワードは「Packages」「importPackage」の2つです。

まず、「Packages」の使用例からです。

▼「Packages」の使用例

var str = new Packages.java.lang.StringBuffer();
str.append("sample");
str.append("test");

Debug.browse( str + "" );

このようにJAVAのAPIのパッケージの前に記述します。これで、変数にはJAVAの「StringBuffer」インスタンスが代入されています。
※実は「Packages」というキーワードは自作のクラスの場合には必要とかどうとか、製品版のintra-martのプログラミングガイドには書いています。

 

次に「importPackage」の使用例です。

▼「importPackage」の使用例

importPackage(Packages.java.lang);
var str = new StringBuffer();
str.append("sample");
str.append("test");

Debug.browse( str + "" );

これは単純にJAVAで言うところのimportと一緒の意味です。パッケージを省略してプログラミングできます。

ちなみにですが、「str + ””」としているのは、この方法によってJAVAのString型の文字列はjavascriptの文字列に変換されるからです。

 

 

「OPEN intra-mart」から「rubbish-db」APIを利用しよう

「rubbish-db」のライブラリをダウンロードするとjarファイルの他にも、APIリファレンスとかサンプルがついてきます。このサンプルの中に「Rhino」から利用した場合のものも含まれています。
まず、それを見てみます。

▼rubbish-db-1.7.5/rhino/src/foo.js

importPackage(Packages.rubbish.db);
importPackage(Packages.rubbish.db.rhino);
JsArrayExtension.extend();

var dbh = new RubbishDatabase();
dbh.logging = true;

dbh.connect("jdbc:hsqldb:hsql://localhost", "sa", "", function(dbh) {
  dbh.query("SELECT ID, NAME FROM PUBLISHER ORDER BY ID", function(row) {
    print(row.id + ": " + row.get("name"));
  });

  dbh.selectBy("PUBLISHER", "ID = ?", "01", function(row) {
    print(row.id + ": " + row.name);
  });

  var rows = dbh.selectBy("PUBLISHER", function(row) {
    row.id = "01";
  });

  rows.each(function(row) {
    print(row.id + ": " + row.get("name"));
  });
});

1〜3行目はパッケージのインポートとNativeJavaArrayの拡張だそうですがよくわかりません取り敢えず決まり文句として使うことにしましょう。

 

5行目でRubbishDatabaseのインスタンス化を行なっています。このインスタンスを使ってDBアクセスを行います。

 

6行目ではDBアクセスに関するログを出力するかを指定しています。trueにした場合、コンソールにログが出力されます。

 

8行目でDBに接続しています。第1引数で接続URL。第2引数でユーザ名。第3引数でパスワード。第4引数でDBに接続して行う処理の関数を指定しています。
第4引数で指定した関数は引数にRubbishDatabaseのインスタンスを受け取ります。その引数を使って関数の中でDBアクセス処理を行うというわけです。
また、この場合、DB切断は第4引数で指定した処理が終了した時点で自動的に行われます。

 

8行目以降については、RubbishDatabaseのインスタンスを使ってDBにアクセスしているだけですので、APIを見てねという感じですが、一つだけ解説すると、13行目で行なっていることは、PUBLISHERテーブルのIDが"01"のレコードを取得してコンソールに出力しています。
引数の解説としては、第1引数で取得するテーブル名、第2引数でWHERE句、第3引数でWHERE句の「?」と置換するパラメータ、第4引数で取得したデータで行う処理の関数を指定しています。第4引数を省略した場合は、DBの取得データが戻り値で受け取れます。

 

サンプルを参考に「OPEN intra-mart」からDBアクセスしてみます。まずサンプルを見て下さい。

▼WebContent/pages/src/test/rubbishdb/rubbishdb.js

/**
 * @fileoverview	DBアクセス確認用
 */

/**
 * 画面表示初期処理
 *
 * @author
 */
function init() {
	importPackage(Packages.rubbish.db);
	importPackage(Packages.rubbish.db.rhino);
	JsArrayExtension.extend();

	// RubbishDatabaseインスタンス作成
	var dbh = new RubbishDatabase();
	// ログ設定
	dbh.logging = true;

	// DB取得値
	var rows;
	/**
	 * DBアクセス処理
	 * @param {IfRubbishDatabase}	dbh
	 */
	function handler(dbh)
	{
		rows = dbh.selectBy("PERSON");
		Debug.print(rows);
	}
	// DBコネクト
	dbh.connect("jdbc:mysql://lubuntumysql:3306/oimart", "root", "mysql", handler);

	Debug.browse(rows);
}	

32行目のDB接続の引数ですが、これは個々人の設定に変更してください。

 

解説ですが、
下準備で作ってもらったPERSONテーブルのレコードを全て取得して、Debug.browseで画面上に表示しています。
また、29行目で行なっているのは、Debug.print関数を使って、取得値をコンソールに表示しています。

 

以上で取り敢えずDBにアクセスできました。

がっ、色々改善の余地がありますので、次回はそのあたりを行います。

 

次回予告

できるだけ読みやすくするように注意はしているのだけれど、読みづらいでですよね。
ほんとスミマセン。
次回からはホント注意しますんで。。。
次回、「DBアクセスを改善する」
みんな笑顔でウルトラハッピー!!

open intra-mart(3)−HelloWorld

さてさて、日が立つのは早いもので前回の記事から1ヶ月がたってしまいました。
正直やることは決まっていたし、サンプルソースはできてたし。
ちょっと、色々と考えることがあったんです。
でもすっきりと決まりました。
  • ZETMAN
  • これはゾンビですか? OF THE DEAD
  • めだかボックス
  • あっちこっち
  • さんかれあ
  • 戦国コレクション
  • 夏色キセキ
  • 咲-Saki- 阿知賀編 episode of side-A
  • つり球
  • 氷菓
を、今期は視ます。

プロジェクト作成

今回はeclipseで開発するわけですが、その開発方法を書いていこうと思います。
eclipseを起動して、「動的Webプロジェクト」を作成してください。
▼プロジェクト>動的Webプロジェクト
動的Webプロジェクト作成
▼プロジェクト作成
プロジェクト作成
1.プロジェクトの作成が完了したら、前回TOMCATに配備した「OPEN intra-mart」から必要なファイルをコピーします。
必要なファイルは以下です。
  • im-jssp-sample/xsl
  • im-jssp-sample/csjs
  • im-jssp-sample/images
  • im-jssp-sample/jssp
  • im-jssp-sample/WEB-INF

プロジェクト直下の「WebContent」以下にフォルダごとコピーしてください。

2.基本的に、これで終了ですが、
「WebContent/WEB-INF/classes/conf/jssp-config.xml」のファイルはSVNのトラックからコピーしてください。
http://oss.intra-mart.org/projects/im-jssp/browser/trunk/im-jssp/src/main/webapp/WEB-INF/classes/conf/jssp-config.xml
このファイルを適用することによって、開発がしやすくなります。
このファイルの意味とかは、後々書くことがあるかも、ないかも。

3.あとは、新規に「WebContent/pages/src」フォルダを作成してください。
このフォルダにプロジェクト内の「WebContent/jssp」フォルダを移動してください。

以上で、プロジェクトの作成は終了です。
▼プロジェクト例
プロジェクト完成図

JSSPについて

intra-martのサーバーサイドjavascriptでページを作成する場合、
サーバー側の処理を行うjsファイルと画面表示のhtmlファイルの2つのファイルをセットで作成する必要があります。

例えば、「sample」というページを作る場合は、「sample.js」と「sample.html」というファイルを作ります。
例のように、同じファイル名である必要があります。
また、ファイルを配置する場所は、プロジェクトの「WebContent/pages/src」フォルダ以下の同じ場所に配置してください。
この「pages/src」というのは先程、プロジェクトにコピーしてもらった「jssp-config.xml」で定義されてある、jsspのファイルを置く場所になっています。
▼JSSPファイル例
jsspファイル例

intra-martにおけるサーバーサイドjavascriptを使った開発では、jsファイルでサーバー側の処理を行い、htmlファイルで、処理したデータを表示するという流れになります。
イメージしにくいと思いますが、「OPEN intra-mart」の公式サイトに
解説がありますので、そちらに譲ることにします。
あと、製品版の「intra-mart」でも開発方法について資料が提供されていますので、そちらも参照してみてください。(※製品版とは異なる箇所がありますのでまるっと鵜呑みにはできませんが。)

ハローワールド

「こんにちは世界」ということで、どっかの主人公が死んじゃうアニメのセリフみたいですが、
サンプルソースです。

▼JSファイル(WebContent/pages/src/hello_world.js)
/**
 * @fileOverview HelloWorld実行サンプル
 * @version
 */

/**
 * @type String
 */
var gMessage;

/**
 * 初期化処理
 * @param {Request}	request	リクエストパラメータ
 */
function init( request )
{
	// グローバル変数に値を格納する
	gMessage = "ハローワールド";
}

▼HTMLファイル(WebContent/pages/src/hello_world.html)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>HelloWorld</title>
</head>
<body>
	<h1>HelloWorld</h1>
	<dl>
		<dt>サーバーサイドで作成した文字列を表示する</dt>
		<dd>
			<imart type="string" value=gMessage ></imart>
		</dd>
	</dl>
</body>
</html>


上記のファイルを指定のパスに配置してください。
あとは、プロジェクトをサーバーで実行すればOKです。
▼サーバーで実行
実行

サーバーの実行が完了したら、以下のURLにアクセスしてください。
「http://localhost:8080/”プロジェクト名”/hello_world.jssp」
▼実行結果
実行結果
こんなかんじに表示されます。

解説

JSSPの解説として以下があります。
jsファイルにinit関数がありますが、これは必ず必要になります。
画面を表示するときに最初に実行されるのはinit関数になるからです。

各ファイルの解説としては
jsファイルでは単純に18行目でグローバル変数の「gMessage」に文字列を代入しています。
以上です。

htmlファイルではそのグローバル変数を表示するようにしています。
13行目に注目してください。imartタグのstringを使用しています。
APIのstringを参照してください。
imartタグ(string)のvalue属性にjsファイルで作成したグローバル変数を指定することができます。
(※もちろんグローバル変数のオブジェクトを作成しておき、そのプロパティの文字列を表示することも可能です。ただし、「arySample[0].strName」のように配列を使うことはできません。)
この際、属性値を「"」で囲んでしまうとただの文字列として扱われてしまうので、グローバル変数を指定する場合は、「"」で囲まないようにしてください。

大体こんな感じです。

次回予告

サンプル作ったら、他にやることあまりない気がする。
次はDBアクセス当たりをやっちゃおうそうしよう。
次回、DBアクセスにィ、レディー・ゴー!

open intra-mart(2)−開発環境を整える

前回は、サーバーサイドjavascriptや「OPEN INTRA-MART」について書きました。

今回は、その「OPEN INTRA-MART」で開発するための環境の構築を書いていきます。


今回の目的

  • 統合開発環境「Eclipse」のインストール
  • 「OPEN INTRA-MART」のインストール
  • DBの構築

推奨環境

というか、自分のマシンでも動いたので、このマシン以上のスペックなら基本的に問題無いと思います。

  • CPU:ATOM330 1.6GHz
  • メモリ:3GB

統合開発環境「Eclipse」のインストール

統合開発環境としては「Eclipse」を使います。

重いと思う方もいるかと思いますが、今回はこれを使います。

まず、「Eclipse」をダウンロードしてください。


自分が必要なものでも結構ですが、例として「Eclipse 3.7.2 Indigo」のJAVA・JREありをダウンロードします。 Eclipseダウンロード ダウンロードが完了しましたら、解凍して任意の場所に配置してください。

「Eclipse」のインストールは以上です。


「OPEN INTRA-MART」のインストール

今回の目的である「OPEN INTRA-MART」をインストールします。


公式サイト:「OPEN INTRA-MART


上記の公式サイトより「im-jssp-sample-0.1.2.war」をダウンロードしてください。

では、ダウンロードしたwarファイルをインストールします。
公式サイトには「Resin」向けのインストール方法は記載されていますが、他のWebアプリケーションへのインストール方法は載っていません。
が、ダウンロードしたwarファイルをデプロイしたらインストールは終わりです。


今回はダウンロードした「Eclipse」に標準で搭載されている「Tomcat」にデプロイします。

Eclipseを起動して、Tomcatを起動してください。

http://localhost:8080/」にアクセスしてください。

「Tomcat Manager」をクリックしてください。
※この際、エラー画面が表示されることがあります。Tomcatのバージョンにもよりますが、7.0の場合だと「tomcat\7.0\conf\tomcat-users.xml」に以下の記述を追加する必要があります。
<role rolename="manager-gui"/>
<user username="admin" password="admin" roles="admin,manager,manager-gui"/>

追加後にTomcatの再起動が必要です。


ユーザ確認ダイアログが出てきますが、デフォルトであれば「ユーザID:admin」「パスワード:admin」でOKです。
まあ、上記の「tomcat-users.xml」に記述されている権限のあるユーザですけど。

開いた画面の下の方にある「WARファイルの配備」でダウンロードしたwarファイルを選択して、「配備」をクリックしてください。
warファイル選択warファイル配備
配備が完了すれば、下図のように、アプリケーションに「/im-jssp-sample」が追加されます。
warファイルデプロイ完了
以上で、インストールは完了です。
http://localhost:8080/im-jssp-sample/」にアクセスしてください。 サンプルを見ることができます。 JSSPサンプルページ

DBの構築

すぐに必要な訳ではないですが、ついでなのでインストールします。 今回は「MySQL」を利用します。 が、直接自分のマシンにインストールするのはなんとなく嫌なので、「VMWare Player」にLinuxを入れて、そこに「MySQL」をインストールします。
「VMWare Player」をインストール

公式サイト:http://www.vmware.com/jp/products/desktop_virtualization/player/overview

参考サイト:http://pc.casey.jp/archives/153894497

上記の公式サイトより「VMWare Player」をダウンロードして、参考サイトを利用してインストールしてください。 特に、難しい箇所はないと思います。


「lubuntu」をインストール

公式サイト:https://help.ubuntu.com/community/Lubuntu/GetLubuntu

参考サイト:http://d.hatena.ne.jp/suikan+embedded/20100620/1277043924

上記の公式サイトより、デスクトップ版の「Lubuntu 11.10 Standard」をダウンロードしてください。

32bit版、64bit版などはどちらでも結構です。ちなみに私は「PC (Intel x86) desktop CD」をダウンロードしました。

参考サイトを参考にして「lubuntu」をインストールしてください。

ここまで書いて何ですが、別に「lubuntu」でなくても問題ないです。「lubuntu」が一番軽いと思ったからです。


「MySQL」をインストール

「VMWare Player」に「lubuntu」のインストールが終わったら、仮想マシンの「lubuntu」を起動してください。仮想マシン上の端末(ターミナル)を起動して以下のコマンドを実行してください。


sudo apt-get install apache2 php5 php5-gd mysql-server php5-mysql system-config-samba

MySqlインストール

上記のコマンドを実行すると、「lubuntu」上にMySQLとphp、samba等がインストールされます。

※途中でMySQLのパスワードを決める必要があります。

※「lubuntu」がインターネットにアクセス出来る必要があります。
「仮想マシン>仮想マシン設定>ネットワークアダプタ」でNATかブリッジを選択して下さい。


「MyWebSQL」をインストール

公式サイト:http://mywebsql.net/

「MyWebSQL」とは「MySQL」の管理ツールです。 必ず必要というわけではありませんが、あったほうがかなり便利だと思います。

利用方法としては、


1.上記の公式サイトよりファイルをダウンロードして解凍してください。
2.解凍したフォルダを「lubuntu」の「/var/www/」直下に配置してください。

MyWebSQL配置

以上です。


ファイルを配置する方法としては、「lubuntu」でダウンロードして配置する方法と、ホストOSでダウンロードしておいて、sambaを利用して配置する方法があります。

sambaを利用する際の注意点としては、「lubuntu」の現在の最新である11.10の場合は以下のコマンドを実行する必要があります。


sudo apt-get install python-glade2


配置が完了したら「lubuntuマシンIP/mywebsql/」にアクセスしてください。

ログイン画面が表示されると思います。

ユーザIDに「root」、パスワードにインストールした時に決めたパスワードを入力してください。

ログインができたと思います。

特にやることは無いので、とりあえずは終了です。


まとめ

長々と書いてきましたが、これで開発環境は整いました。
  • Eclipse
  • MySQL
が利用できるようになりました。

予告

下準備に時間かけすぎでしょうがっ!

と思った。

時間があるときに書けばいいのにと思った。

基本的に時間のない俺は・・・

『Hello World』