天天看點

Scripting IntroductionScripting Introduction

Scripting Introduction

DWR根據dwr.xml生成和Java代碼類似的Javascript代碼。

相對而言Java同步調用,建立與Java代碼比對的Ajax遠端調用接口的最大挑戰來至與實作Ajax的異步調用特性。

DWR通過引入回調函數來解決這個問題,當結果被傳回時,DWR會調用這個函數。

有兩種推薦的方式來使用DWR實作遠端方法調用。可以通過把回調函數放在參數清單裡,也可以把回調函數放到中繼資料對象裡。

當然也可以把回調函數做為第一個參數,但是不建議使用這種方法。因為這種方法在處理自動處理http對象時(檢視"Alternative Method")上會有問題。這個方法主要是為向下相容而存在的。

簡單的回調函數

假設你有一個這樣的Java方法:

public class Remote {
    public String getData(int index) { ... }
}           

複制

我們可以在Javascript中這樣使用:

<script type="text/javascript"
    src="[WEBAPP]/dwr/interface/Remote.js"> </script>
<script type="text/javascript"
    src="[WEBAPP]/dwr/engine.js"> </script>
...

function handleGetData(str) {
  alert(str);
}

Remote.getData(42, handleGetData);           

複制

42是Java方法getData()的一個參數。

此外你也可以使用這種減縮格式:

Remote.getData(42, function(str) { alert(str); });           

複制

調用中繼資料對象(Meta-Data)

另外一種文法時使用"調用中繼資料對象"來指定回調函數和其他的選項。上面的例子可以寫成這樣:

Remote.getData(42, {
  callback:function(str) { alert(str); }
});           

複制

這種方法有很多優點:易于閱讀,更重要的指定額外的調用選項。

逾時和錯誤處理

在回調函數的中繼資料中你可以指定逾時和錯誤的處理方式。例如:

Remote.getData(42, {
  callback:function(str) { alert(str); },
  timeout:5000,
  errorHandler:function(message) { alert("Oops: " + message); }
});           

複制

查找回調函數

有些情況下我們很難區分各種回調選項(記住,Javascript是不支援函數重載的)。例如:

Remote.method({ timeout:3 }, { errorHandler:somefunc });           

複制

這兩個參數之一是bean的參數,另一個是中繼資料對象,但是我們不能清楚的告訴DWR哪個是哪個。為了可以跨浏覽器,我們假定null == undefined。 是以目前的情況,規則是:

  • 如果第一個或最後一個是一個函數,那麼它就是回調函數,沒有中繼資料對象,并且其他參數都是Java的方法參數。
  • 另外,如果最後一個參數是一個對象,這個對象中有一個callback成員,并且它是個函數,那麼這個對象就是中繼資料對象,其他的都是Java方法參數。
  • 另外,如果第一個參數是 null ,我們就假設沒有回調函數,并且其他的都是Java方法參數。盡管如此,我們會檢查最後一個參數是不是null,如果是就發出警告。
  • 最後如果最後一個參數是null,那麼就沒有callback函數。
  • 另外,發出錯誤信号是個糟糕的請求格式。

創造一個與Java對象比對的Javascript對象

假設你有這樣的Java方法:

public class Remote {
  public void setPerson(Person p) {
    this.person = p;
  }
}           

複制

Person對象的結構是這樣的:

public Person {
  private String name;
  private int age;
  private Date[] appointments;
  // getters and setters ...
}           

複制

那麼你可以在Javascript中這樣寫:

var p = {
  name:"Fred Bloggs",
  age:42,
  appointments:[ new Date(), new Date("1 Jan 2008") ]
};
Remote.setPerson(p);           

複制

在Javascript沒有出現的字段,在Java中就不會被設定。

因為setter都是傳回'void',我們就不需要使用callback函數了。如果你想要一個傳回void的服務端方法的完整版,你也可以加上callback函數。很明顯DWR不會向它傳遞任何參數。