- 追加された行はこの色です。
- 削除された行はこの色です。
*Java:Rhino:初めてのRhino [#w4da3443]
JavaからJavaScriptを実行できる、Rhinoを使って見ました。
これから、Webページのスクレイピングで使おうとおもってます。Javaでやるより、JQueryとか使った方が楽そうだもんねw
***環境設定 [#xcd50f48]
Rhinoのjarにクラスパスが通っているだけでOKです。
Rhinoのjarは以下のURLよりDLします。
-https://developer.mozilla.org/en-US/docs/Rhino/Download_Rhino?redirectlocale=en-US&redirectslug=RhinoDownload
※日本語ページもありますが、日本語の方はバイナリが古いです。更新もされてないみたいだし。
***ソースコード [#o1d4389f]
RhinoをつかってJavaScriptを読み込み、JavaScriptに定義されている関数を任意のタイミングで呼び出す、ってサンプルです。
ファイルは以下の2つです。
-sample.js
-RhinoFirstSample.java
まず、JavaScriptのソースコード。
■sample.js
function sample(){
print("hello world");
print("This output is from JavaScript.");
return "Return value";
};
他愛もないjsです。
次にjavaのソースコード。大雑把に、以下の内容を実行してます。
-コンストラクタ:Rhinoの初期可処理をしてます。
--Rhinoのシェルにしかない関数(print等)を使用したいために、Globalオブジェクトを生成し、スコープ生成の際に引数として渡しています。
-execScriptメソッド:引数に指定されたスクリプトを実行します。
-execFunctionメソッド:引数に指定された関数名及び引数から、関数を実行する1行のJavaScript文を生成し、実行します。
まあ、ポイントはコードを読んでもらえればw
コンストラクタ→execScriptメソッド→execFunctionメソッド→contextExitメソッドの順に処理が流れています。
※mainの中身どおりw
■RhinoFirstSample.java
package rhinotest;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.tools.shell.Global;
public class RhinoFirstSample {
private Global global = null;
private Context cx = null;
private Scriptable scope = null;
/**
* コンストラクタ
* Rhinoの初期化処理を実行
*/
public RhinoFirstSample() {
// コンテキストの生成
cx = ContextFactory.getGlobal().enterContext();
// shellでしか使えない関数(print等)を使用するため、使用
global = new Global();
global.init(cx);
// optimazationのレベルを指定。-1だと、Scriptを逐次解釈する。
// 1-9だと、レベルに応じて適切にclassファイルを生成する。
cx.setOptimizationLevel(-1);
cx.setLanguageVersion(Context.VERSION_1_5);
// スタンダードオブジェクトを生成。
// Javadocには「return: the initialized scope」と記載あり。
scope = cx.initStandardObjects(global);
}
/**
* 指定されたパス、ファイル名のJavaScriptを実行する。
* @param path
* @param filename
* @throws IOException
*/
public void execScript(String path, String filename) throws IOException {
Reader scriptReader = new FileReader(path + File.separator + filename);
Script script = cx.compileReader(scriptReader, filename, 1, null);
scriptReader.close();
script.exec(cx, scope);
}
/**
* 指定された関数を実行する。
* 以下の場合、実行行を以下のように組み立て、スクリプトとして実行する。
* jsFuncName:testFunc
* args : ["test1","test2"]
* => testFunc("test1","test2");
* @param jsFuncName : 関数名を指定
* @param args : 引数をString配列で指定、引数がない場合は空の配列もしくはnullも可
* @return
*/
@SuppressWarnings("static-access")
public String execFunction(String jsFuncName,String[] args){
StringBuffer execLine = new StringBuffer();
execLine.append(jsFuncName + "(" );
if(args != null){
for(int i=0; i < args.length; i++){
execLine.append("\"");
execLine.append(args[i]);
execLine.append("\"");
if (i != args.length){
if (i != args.length-1){
execLine.append(",");
}
}
}
execLine.append(");");
Object result = cx.evaluateString(scope, execLine.toString(), "<cmd>",
1, null);
return cx.toString(result);
}
/**
* Rhinoのコンテキストをクローズする。
* RhinoのJavadocに、exit()しろってかいてあったので書いてみた。
*/
public void contexExit(){
Context.exit();
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
RhinoFirstSample rhino = null;
try{
rhino = new RhinoFirstSample();
final String RESOURCE_PATH = "bin/resources";
rhino.execScript(RESOURCE_PATH, "sample.js");
System.out.println("This output is java(println) : "
+ rhino.execFunction("sample", null));
}finally{
rhino.contexExit();
}
}
}
***実行結果 [#c95baf48]
こんな感じです。
hello world
This output is from JavaScript.
This output is java(println) : Return value
うん、いい感じw
***参考 [#k00c664c]
-MOZILLA-japanのチュートリアル&BR;http://www.mozilla-japan.org/rhino/tutorial.html#runScript
Rhinoのjavadocがアーカイブに含まれているため、これをちゃんと見ましょう。
特に、以下のクラスについてはw
-ContextFactory
-Context