背景
背景から始めたいと思います。 現時点では、ある種のJava Webアプリケーションを開発していますが、これは珍しいことではありませんが、ドキュメントには顧客からの要件があります。将来のアプリケーション管理者は、サーバーにビジネスロジックコードをオンザフライでロードできるはずです。 超自然的なことではないように思えますが、Javaクラスをロードする必要があると思います。最近まで、「JavaScriptでビジネスロジックメソッドをプログラミングする機会を与えたらどうなるでしょうか」という考えが浮かびました。
その瞬間、このアイデアは私にとって非常に良さそうに見え、Javaクラスの単純なロードを超えるこのアイデアの多くの利点を見ました。
- まず、JavaScriptはロジックを記述するための非常に単純な言語です; OOPの原理とCのような構文に精通しているプログラマーなら誰でも書くことができます。
- 第二に、なぜなら 外部サーバーAPIはRESTスタイルで設計されており、jsコードはリソースのフレームワークに完全に収まり、問題なくJSON文字列にシリアル化でき、コンパイルや追加の操作は不要です。
- 第三に、インタープリターによるJavaScriptコードの実行は、セキュリティサンドボックス内でのコードの実行であり、ビジネスロジックコードの動作のルールを明確に構成できます。
しかし、大きな力は大きな責任であることを忘れないでください。そのため、新しい機会の後、詳細な答えを必要とする新しい質問が生じます。
この記事では、純粋なjsでビジネスロジックを記述するという考え方について簡単に説明し、理論的および実用的な部分に触れ、この決定後に生じる可能性のあるニュアンスのいくつかについて説明したいと思います。
JavaScriptインタープリターの選択
jsを解釈するエンジンに遅れをとる必要はありませんでした。最初の候補はMozilla Rhinoです-jsエンジンは完全にJavaで書かれています。
このエンジンは、1997年にNetscapeの壁に「Javagator」という名前で生まれましたが、その後、不思議な状況下でRhinoと改名されました。 Rhinoは、そのプロジェクトのためにいくつかの大企業(Sunを含む)によってライセンスされています。 最初は、JavaScriptに基づいてJavaバイトコードをコンパイルするというアイデアでしたが、このアプローチにはいくつかの問題がありました。
- まず、クラスのコンパイルとロードのプロセスは少し重く、
- 第二に、メモリリークが発生することがありました。
1998年に、デフォルトでインタープリターモードがエンジンに追加されました。 JavaScriptコードは、バイトコードへのコンパイルをバイパスして、オンザフライで実行されます。 これにより、大量のコンパイルやメモリリークの問題が回避されました。 今年後半、エンジンはソースコードを開き、mozilla.orgに提供されます。
ライブラリのバイナリとソースコードは、公式Webサイト(サイト
へのリンク)からダウンロードできます。 例ではrhino1.7 R4を使用します。
Rhinoは2つの方法で使用できます。コマンドラインから使用する方法と、プロジェクトにjarファイルを埋め込む方法です。 ここで、まさに2番目の方法に興味があります-js.jarファイルをプロジェクトに追加します。
LiveConnectテクノロジー
Rhinoの主なアイデアの1つは、LiveConnectテクノロジーを使用してJavaScriptコードを使用してJavaサーバーをプログラムする機能です。 この技術により、サードパーティのコードに頼ることなく、jsからJavaクラスに直接アクセスできます。
File
クラスと
System
クラスにアクセスする小さな例を次に示します。
var f = new java.io.File(“test.txt”); java.lang.System.out.println(f.exists());
LiveConnectは、私たちに多くの行動の余地を与えてくれます。それについてはオフィスでたくさん書かれています。 エンジンのドキュメントですが、今は詳しく説明しません。 Javaクラスへのアクセス権を持たない信頼できない外部ソースからのコードの解釈に興味があります。
Rhinoを使用する
例として、大学の仮想プロジェクト「学生会計および学年会計サービス」のためのシンプルなビジネスロジックモジュールを開発します。 アプリケーションは、すべての生徒と成績のリストを保持し、タスクに基づいて生徒に対して何らかのアクションを実行できる必要があります。
使用の基本から始めましょう。 Rhinoには2つの主要な概念があります-これはコンテキスト(クラス
org.mozilla.javascript.Context
)とスコープ(クラス
org.mozilla.javascript.Scriptable
)です。 コンテキストは、単一のスレッドにバインドするインタープリターインスタンスであるため、単一のスレッドでjsを解釈します。 球体は、名前空間と呼ばれるもので、対象となるすべての変数を定義します。
コンテキストとスコープを作成する例:
コンテキストとスコープを作成したら、Javaクラスへのインタープリターアクセスを制限する必要があります。 これは、
setClassShutter
インスタンスの
setClassShutter
メソッドを使用して行われます。
デフォルトでは、RhinoはLiveConnectテクノロジーを使用します。これにより、jsから直接Javaクラスにアクセスできます。 信頼できるコードに大きなチャンスを与えますが、別のケースがあります-サーバーは潜在的に安全でないコードを解釈します。
次の形式のjs-codeがインタープリターに入ると、非常に不快になります。
java.lang.System.exit(0);
したがって、単にLiveConnectを「プラグ」し、必要なクラスへのアクセスのみを残します。 コンテキストとスコープを取得したら、jsコードを解釈する以外に方法はありません。
String script = “var mathStuff = Math.cos(Math.PI)”; c.evaluateString(scope, script, null, 1, null);
Rhinoを使用した後、コンテキストの使用を終了し、リソースを解放します。
Context.exit();
ビジネスロジック用の「サンドボックス」
Rhinoの使用を開始する方法がわかったので、次に、トップレベルモジュールへのいくつかの定数リンクの形式で外部ビジネスロジックAPIを定義することに進みます。
- データベースとの通信を担当するDatabaseModule、
- NotificationModule 、いくつかのイベントについてシステムのユーザーに通知する責任があります。
public class DatabaseModule { public DatabaseModule(){ } public String getStudent(int id){ return (id > 0) ? " " : null; } public int getRating(String student){ return student.equals(" ") ? 5 : -1; } public void setRating(String student, int newRating){ System.out.println("setRating() student = "+student+", newRating = "+newRating);
public class NotificationModule { public NotificationModule(){ } public void notifyStudent(String student, String message){ System.out.println("notifyStudent() student = "+student+", message = "+message); } public void notifyCurator(String message){ System.out.println("notifyCurator() message = "+message); } }
次に、以前に定義した領域のモジュールへの定数リンクを定義します。
JavaScriptビジネスロジックプログラミング
データベースから学生に関する情報を識別子で選択し、成績を取得し、試験に入学するのに十分なポイントがあるかどうかを計算し、学芸員と学生自身に通知するタスクがあるとします。 この場合、タスク全体がそのようなjs-codeに分類されます。
var student = databaseModule.getStudent(1); var rating = databaseModule.getRating(student); var pass = rating >= 40; if(pass){ notificationModule.notifyCurator("Student "+student+" is admitted to the exam."); notificationModule.notifyStudent(student, "You admitted to the exam."); } else { var dif = 40 - rating; notificationModule.notifyCurator("Student "+student+" needs "+dif+" points to be admitted to the exam."); notificationModule.notifyStudent(student, "You need "+dif+" points to be admitted to the exam."); }
残っているのは、インタープリターを構成してjsを渡すことだけです。 すぐに警告します。エンジンはキリル文字を痛感します。
おわりに
結論として、jsでビジネスロジックをプログラミングするというアイデアは、新しいものではありませんが、非常に興味深いものです。 このアプローチは、柔軟性と実装の容易さを提供します。
新しいメソッドを追加するタスクに直面しているプログラマーは、サーバー側でどのテクノロジースタックが使用されているかを考える必要はなく、単に何をする必要があるかを規定し、機能を簡単に拡張および補完します。
このアプローチによって提供される機会に続いて、戦闘サーバーに実装する前に注意しなければならないいくつかの質問があります。
- スクリプトのセキュリティ:再帰と無限ループがありますか、メモリの読み込みが多すぎますか、
- スクリプトの検証:正しく記述されているか、サーバーAPIと正しく対話するか、
- サーバーセキュリティ:スクリプトがアクセスできるモジュール。
幸いなことに、すべての問題は完全に解決可能であり、Rhinoのソースコードは修正のために公開されています。
便利なリンク
の。 プロジェクトのウェブサイト:
https :
//developer.mozilla.org/en/docs/Rhinoウィキペディアの記事:
http :
//en.wikipedia.org/wiki/Rhinoの。 ドキュメント:
https :
//developer.mozilla.org/en-US/docs/Rhino_documentationAPIリファレンス(ではない):
Http :
//tool.oschina.net/uploads/apidocs/rhino/GitHubサンプルのソース:
https :
//github.com/andrew-medvedev/rhino-example