LiveConnect 類別的使用

 

LiveConnect 類別的使用

所有在 Java 代碼中的 JavaScript 物件都是以 netscape.javascript.JSObject 的實體呈現的。當你在你的 Java 代碼內部呼叫方法時,你可以把 JavaScript 物件當作方法的其中一個參數來傳入。要做到這一點,你必須定義能夠對應於 JSObject 類型的方法的參數形式。

除此之外,當你在 Java 代碼中使用 JavaScript 物件的任何時候,你就要把使用到 JavaScript 物件的呼叫放置於 try...catch 語法之中,並處理 netscape.javascript.JSException 類型的例外。如此一來,當執行 JavaScript 代碼並出現 JSException 類型的例外時,就可讓你的 Java 代碼處理這些錯誤。

使用 JSObject 存取 JavaScript

舉例來說,假定你正在使用稱為 JavaDog 的 Java 類別。如同下面的代碼所示,JavaDog 建構子可接受 JavaScript 物件 jsDog,這個物件被定義成和參數一樣的 JSObject 類型︰

import netscape.javascript.*;

public class JavaDog
{
    public String dogBreed;
    public String dogColor;
    public String dogSex;

    // define the class constructor
    public JavaDog(JSObject jsDog)
    {
        // use try...catch to handle JSExceptions here
        this.dogBreed = (String)jsDog.getMember("breed");
        this.dogColor = (String)jsDog.getMember("color");
        this.dogSex = (String)jsDog.getMember("sex");
    }
}

注意 JSObjectgetMember 方法是用來存取 JavaScript 物件的屬性。這個例子中使用 getMember 把 JavaScript 的 jsDog.breed 屬性值代給 Java 的資料成員 JavaDog.dogBreed

附註: 更接近實際使用的例子會把 getMember 的呼叫放置在 try...catch 語法的內部,以處理 JSException 類型的錯誤。詳見 在 Java 中處理 JavaScript 例外 以取得更多資訊。

為了獲得對 getMember 如何運作的良好感覺,仔細閱讀自訂 JavaScript 的物件 Dog 的定義︰

function Dog(breed,color,sex) {
   this.breed = breed
   this.color = color
   this.sex = sex
}

你可以如下呼叫 gabby 來建立 JavaScript 的 Dog 實體︰

gabby = new Dog("lab","chocolate","female")

如果你對 gabby.color 求值,你會看到他的值是 "chocolate"。現在假定你在你的 JavaScript 代碼中把 gabby 物件傳給建構子並建立 JavaDog 的實體如下︰

javaDog = new Packages.JavaDog(gabby)

如果你對 javaDog.dogColor 求值,你會看到他的值也是 "chocolate",因為在 Java 的建構子中的 getMember 方法會把 gabby.color 的值代給 dogColor

在 Java 中處理 JavaScript 例外

當在 Java 裡被呼叫的 JavaScript 代碼在執行時期失敗的時候,他就會拋出例外。如果你有意在 Java 裡呼叫 JavaScript 代碼,你可以在 try...catch 區塊裡捕捉例外。在你的 Java 代碼中可以取得形如 netscape.javascript.JSException 實體的 JavaScript 例外。

JSException 即包裝了由 JavaScript 拋出的所有例外類型的 Java 包裝器,類似於用在 JavaScript 物件的包裝器 JSObject 實體的運作方式。當你在 Java 代碼中對 JavaScript 求值時可以使用 JSException

當你在 Java 中對 JavaScript 代碼求值的時候,下列情況便會導致執行時期錯誤︰

  • JavaScript 代碼並未被求值,原因可能出在 JavaScript 編譯上的錯誤或在執行時期所發生的某些其他錯誤。JavaScript 解譯器產生的錯誤訊息會被轉換成 JSException 的實體。
  • Java 成功的對 JavaScript 代碼求值,但 JavaScript 代碼執行的是未經處理的 throw 語法。JavaScript 拋出的例外是被包裝成 JSException 的實體。可以使用 JSException 的 getWrappedException 方法在 Java 中解開例外。

舉例來說,假設 Java 物件 eTest 會對你所傳入的字串 jsCode 求值。你可以藉由例外處理器的實行,來回應求值時所產生的任何一種執行時期錯誤的類型︰

import netscape.javascript.JSObject;
import netscape.javascript.JSException;

public class eTest {
    public static Object doit(JSObject obj, String jsCode) {
        try {
            obj.eval(jsCode);
        } catch (JSException e) {
            if (e.getWrappedException()==null)
                return e;
            return e.getWrappedException();
        }
        return null;
    }
}

在本範例中,在 try 區塊裡的代碼試圖對你所傳入的字串 jsCode 求值。就讓我們假設你傳入了字串 "myFunction()" 當作 jsCode 的值。如果 myFunction 並未定義成 JavaScript 的函數,JavaScript 解譯器無法對 jsCode 求值。解譯器便會產生錯誤訊息,Java 處理器捕捉到錯誤訊息,然後 doit 方法會返回 netscape.javascript.JSException 的實體。

然而,假設 myFunction 已在 JavaScript 中定義如下︰

function myFunction() {
   try {
      if (theCondition == true) {
         return "Everything's ok";
      } else {
         throw "JavaScript error occurred" ;
      }
   } catch (e) {
      if (canHandle == true) {
         handleIt();
      } else {
         throw e;
      }
   }
}

如果 theCondition 為 false,函數就會拋出例外。例外會在 JavaScript 代碼中被捕捉,如果 canHandle 為 true,JavaScript 就會處理例外。如果 canHandle 為 false,就會再度拋出例外,Java 處理器捕捉到例外,然後 doit 方法返回 Java 字串︰

JavaScript error occurred

詳見 例外處理語法 以取得有關 JavaScript 例外的完整資訊。

向後相容性

在 JavaScript 1.3 及早期版本中,JSException 類別具有三個公開的建構子可選擇性的接受字串參數,這個參數可指明詳細的訊息或其他有關例外的資訊。getWrappedException 無法使用。

使用 try...catch 語法如下,以在 JavaScript 1.3 及其早期版本中處理 LiveConnect 例外︰

try {
   global.eval("foo.bar = 999;");
} catch (Exception e) {
   if (e instanceof JSException) {
      jsCodeFailed()";
   } else {
      otherCodeFailed();
   }
}

在本例子中,如果 foo 尚未定義,eval 語句就會失敗。如果 eval 語句在 try 區塊中拋出 JSExceptioncatch 區塊就會執行 jsCodeFailed 方法;如果 try 區塊拋出其他的錯誤,就會執行 otherCodeFailed 方法。

文件標籤與貢獻者

 最近更新: teoli,