1、DWR簡介
DWR是一個遠端web調用架構,利用該架構使得Ajax開發變得簡單。利用DWR可以在用戶端使用JavaScript直接調用伺服器端的Java方法,并傳回值給JavaScript;就好像直接在本地用戶端調用一樣(DWR根據Java類來動态生成JavaScript代碼)。
DWR包含兩部分:
- 一個運作在伺服器端的 Java Servlet,它處理請求并且向浏覽器發回響應。
- 運作在浏覽器端的 JavaScript,它發送請求而且還能動态更新網頁。
2、DWR工作原理
通過動态把 Java 類生成為 Javascript。它的代碼就像 Ajax 魔法一樣,你感覺調用就像發生在浏覽器端,但是實際上代碼調用發生在伺服器端,DWR 負責資料的傳遞和轉換。這種從 Java 到JavaScript的遠端調用功能的方式使DWR用起來有種非常像RMI或者SOAP的正常RPC機制,而且DWR的優點在于不需要任何的網頁浏覽器插件就能運作在網頁上。
Java 從根本上講是同步機制,然而 AJAX 卻是異步的。是以你調用遠端方法時,當資料已經從網絡上傳回的時候,你要提供有回調 (callback) 功能的 DWR。(通過回調函數來異步處理Java的函數調用過程)。
DWR 動态在 JavaScript 裡生成一個 AjaxService 類,去比對伺服器端的代碼。eventHandler 方法去調用伺服器端代碼,然後 DWR 處理所有的遠端細節,包括轉換(converting) 所有的參數以及傳回 Javascript 和 Java 之的值。在示例中,先在 eventHandler 方法裡調用 AjaxService 的 getOptions() 方法,然後通過回調方法 populateList(data) 得到傳回的資料,其中 data 就是 String[]{"1", "2", "3"},最後再使用 DWR utility 把data 加入到下拉清單。
3、DWR2.0示例代碼——該示例中使用Maven建立WebApp項目
1)準備工作,建立一個Web項目,并建立domain層實體類——User,模拟DAO層——UserDao
User.java檔案:
package com.techlogy.dwr.domain;
public class User {
private int id;
private String name;
private String password;
private String email;
public User() {
}
public User(String name, String password, String email) {
this.name = name;
this.password = password;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
UserDao.java檔案:
package com.techlogy.dwr.dao;
import java.util.HashMap;
import java.util.Map;
import com.techlogy.dwr.domain.User;
public class UserDao {
private static Map<Integer,User> db=new HashMap<Integer ,User>();
public boolean save(User usr){
User user=(User) db.get(usr.getId());
if(user!=null){
System.out.println("資料庫中使用者已經存在,無法儲存!");
return false;
}
//資料庫中不存在該使用者時,儲存
db.put(usr.getId(), usr);
System.out.println("使用者儲存成功!");
return true;
}
public User findById(Integer id){
User user=db.get(id);
return user;
}
}
2)模拟業務邏輯層——DWRUserService,其中建立兩個方法saveUser方法和findUserById方法。該類供DWR架構遠端調用。
package com.techlogy.dwr.service;
import com.techlogy.dwr.dao.UserDao;
import com.techlogy.dwr.domain.User;
public class DWRUserService {
private UserDao usrDao=new UserDao();
public boolean saveUser(User usr){
return usrDao.save(usr);
}
public User getUserById(Integer id){
return usrDao.findById(id);
}
}
3)web.xml配置檔案:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>dwr</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<!-- 是否允許調試,設為true,才能允許調試DWR架構的遠端方法。 -->
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<!-- 注意:将該項值設為true,回調函數(用于處理Java函數的傳回值)才能在浏覽器端起作用。
否則,回調函數不會起作用。 -->
<init-param>
<param-name>allowScriptTagRemoting</param-name>
<param-value>true</param-value>
</init-param>
<!-- 設為true,網頁才能顯示出來
<init-param>
<param-name>scriptCompressed</param-name>
<param-value>false</param-value>
</init-param> -->
<!-- 是否進行日志管理 -->
<init-param>
<param-name>logLevel</param-name>
<param-value>DEBUG</param-value>
</init-param>
<!--如果允許跨域請求,則将其設定為false。預設為true。 -->
<init-param>
<param-name>crossDomainSessionSecurity</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
</web-app>
4)dwr.xml配置檔案:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
"http://getahead.org/dwr/dwr20.dtd">
<dwr>
<allow>
<!-- creator元素将DWRUserService類轉換為DWRUserService.js代碼 -->
<create creator="new" javascript="DWRUserService">
<param name="class" value="com.techlogy.dwr.service.DWRUserService"/>
</create>
<convert converter="bean" match="com.techlogy.dwr.domain.User"/>
</allow>
</dwr>
5)測試jsp頁面——index.jsp,在該頁面中一定要引入engine.js檔案,util.js檔案視使用而定。但得注意,需要引入DWR架構生成的DWRUserService.js代碼檔案,如下。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>DWR示例</title>
<script type="text/javascript" src="engine.js"></script>
<script type="text/javascript" src="util.js"></script>
<script type="text/javascript" src="useraccess.js"></script>
<script type="text/javascript" src="/dwrDemo/dwr/interface/DWRUserService.js"></script>
<script type="text/javascript">
window.onload=function(){
var saveBtn=document.getElementById("saveBtn");
saveBtn.onclick=OnSave;
var queryBtn=document.getElementById("queryBtn");
queryBtn.onclick=OnFind;
};
</script>
</head>
<body>
<h1>使用者注冊</h1>
<form name="regForm">
user ID:<input type="text" name="id"><br/>
username:<input type="text" name="name"><br/>
password:<input type="text" name="password"><br/>
email:<input type="text" name="email"><br/>
<input id="saveBtn" type="button" value="送出">
</form>
<hr/>
<h1>使用者查詢</h1>
<form name="queryForm">
登陸ID:<input type="text" name="id"><br>
<input id="queryBtn" type="button" value="查詢"><br>
</form>
</body>
</html>
6)處理Java傳回值得回調函數js代碼——useraccess.js
function saveFun(data) {
if (data) {
alert("注冊成功!");
} else {
alert("登陸ID已經存在!");
}
}
function OnSave() {
var userMap = {};
//var regForm=document.getElementsByName("regForm")[0];
userMap.id = regForm.id.value;
userMap.password = regForm.password.value;
userMap.name = regForm.name.value;
userMap.email = regForm.email.value;
DWRUserService.saveUser(userMap, saveFun);//saveFun為回調函數
console.log(userMap);
}
function findFun(data) {
if (data == null) {
alert("無法找到使用者:"+queryForm.id.value);
return;
}
alert("找到使用者,nid:"+data.id+",npassword:"+data.password+",nname:"+data.name+",nemail:"+data.email);
}
function OnFind() {
//var queryForm=document.getElementsByName("queryForm")[0];
console.log(queryForm.id.value);
DWRUserService.getUserById(queryForm.id.value, findFun);//findFun為回調函數
}
7)測試結果
- 使用者注冊結果:注冊成功
- 再次注冊相同ID使用者,出現以下結果:
- 查找ID為3的使用者,回調函數處理結果:
- 查找一個ID不存在的使用者,處理結果如下:
以上是我個人的學習心得分享一下,皮毛之事。