??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产精品一区二区第一页,91热爆在线观看,国产粉嫩在线观看http://www.aygfsteel.com/jesson2005/articles/111007.html张金?/dc:creator>张金?/author>Mon, 16 Apr 2007 08:29:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111007.htmlhttp://www.aygfsteel.com/jesson2005/comments/111007.htmlhttp://www.aygfsteel.com/jesson2005/articles/111007.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111007.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111007.html來寫個AJAX版的聊天室吧Q先看看直接使用AJAX要如何做刎ͼ首先需要一個簡單的聊天室Servlet…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package onlyfun.caterpillar;
 
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.List;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class ChatRoomServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
private static LinkedList<Message> messages = new LinkedList<Message>();

public ChatRoomServlet() {
super();
}

private List<Message> addMessage(String text) {
if (text != null && text.trim().length() > 0) {
messages.addFirst(new Message(text));
while (messages.size() > 10) {
messages.removeLast();
}
}
 
return messages;
}
 
private List<Message> getMessages() {
return messages;
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Message> list = null;

if("send".equals(request.getParameter("task"))) {
list = addMessage(request.getParameter("msg"));
}
else if("query".equals(request.getParameter("task"))){
list = getMessages();
}
 
PrintWriter out = response.getWriter();
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
 
out.println("<response>");
for(int i = 0; i < list.size(); i++) {
String msg = list.get(i).getText();
out.println("<message>" + msg + "</message>");
}
out.println("</response>");
}
}


Message物g如下…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package onlyfun.caterpillar;
 
public class Message {
private long id = System.currentTimeMillis();
private String text;

public Message(String newtext) {
text = newtext;
if (text.length() > 256) {
text = text.substring(0, 256);
}
text = text.replace('<', '[');
text = text.replace('&', '_');
}
 
public long getId() {
return id;
}
 
public String getText() {
return text;
}
}


Servlet接受a息新增與查詢,判斷的方式是檢查請求參數task是send或query?

Servlet會以XML傛_目前List當中的訊息,客戶端可以查詢或插入新訊息時Q取得目前List中的a息Q接著在web.xml中設定一?#8230;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<description>
</description>
<display-name>
ChatRoomServlet</display-name>
<servlet-name>ChatRoomServlet</servlet-name>
<servlet-class>
onlyfun.caterpillar.ChatRoomServlet</servlet-class>
</servlet>
 
<servlet-mapping>
<servlet-name>ChatRoomServlet</servlet-name>
<url-pattern>/ChatRoomServlet</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
</web-app>


在網頁中Q用者可以在輸入a息後按下按鈕送出資訊Q並在XML回應取得時,訊息以一列一列的表格方式示ZQ另外還a定了週期性的輪詢Q即使不輸入新訊息,也可以週期性的取得新的聊天a息…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Chat Room</title>
 
<script type="text/javascript">
var xmlHttp;
 
function createXMLHttpRequest() {
if (window.ActiveXObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}
}
 
function sendMessage() {
var msg = document.getElementById("text").value;

if(msg == "") {
refreshMessage();
return;
}

var param = "task=send&msg=" + msg;
ajaxRequest(param);
document.getElementById("text").value = "";
}
 
function queryMessage() {
var param = "task=query";
ajaxRequest(param);
}
 
function ajaxRequest(param) {
var url = "ChatRoomServlet?timestamp" + new Date().getTime();
createXMLHttpRequest();
xmlHttp.onreadystatechange = refreshMessage;
xmlHttp.open("POST", url, true);
xmlHttp.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded;");
xmlHttp.send(param);
}

function refreshMessage() {
if(xmlHttp.readyState == 4) {
if(xmlHttp.status == 200) {
var messages = xmlHttp.responseXML.getElementsByTagName("message");

var table_body = document.getElementById("dynamicUpdateArea");
var length = table_body.childNodes.length;
for (var i = 0; i < length; i++) {
table_body.removeChild(table_body.childNodes[0]);
}

var length = messages.length;
for(var i = length - 1; i >= 0 ; i--) {
var message = messages[i].firstChild.data;
var row = createRow(message);

table_body.appendChild(row);
}
setTimeout("queryMessage()", 2000);
}
}
}
 
function createRow(message) {
var row = document.createElement("tr");
var cell = document.createElement("td");
var cell_data = document.createTextNode(message);
cell.appendChild(cell_data);
row.appendChild(cell);
return row;
}
 
</script>
 
</head>
<body>
 
<p>
Your Message:
<input id="text"/>
<input type="button" value="Send"
onclick="sendMessage()"/>
</p>
 
<p>Messages:</p>
<table align="left">
<tbody id="dynamicUpdateArea"></tbody>
</table>
 
</body>
</html>


單抓個畫?#8230; 


直接用AJAXQ後端用JSP/ServletQ您要對請求參數做些判斷Q看看是新增a息或查詢,並要自行輸出XMLQ有的沒?#8230;

ҎDWR的話Q就很簡單了Q寫個簡單的Java物g…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package onlyfun.caterpillar;
 
import java.util.LinkedList;
import java.util.List;
 
public class Chat {
private static LinkedList<Message> messages = new LinkedList<Message>();
 
public List addMessage(String text) {
if (text != null && text.trim().length() > 0) {
messages.addFirst(new Message(text));
while (messages.size() > 10) {
messages.removeLast();
}
}

return messages;
}
 
public List getMessages() {
return messages;
}
}


接著…在dwr.xml中開放一?#8230;
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">

<dwr>
<allow>
 
<create creator="new" javascript="Chat">
<param name="class" value="onlyfun.caterpillar.Chat"/>
</create>

<convert converter="bean" match="onlyfun.caterpillar.Message"/>
</allow>
</dwr>


使用者取得訊息時Q是直接傛_List物gQ而List中裝的是Message物gQMessage物g是自a物Ӟcontervera定?beanQ表CDWR會自動將Message的getter名稱轉換為傳回客戶端的JavaScript物g中的屬性,例如Message中有 getText()Q則在客戶端可以用message.text這樣的方式來存取?

接著是簡單的客戶端網?#8230;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Insert title here</title>
 
<script src="dwr/interface/Chat.js" type="text/javascript"></script>
<script src="dwr/engine.js" type="text/javascript"></script>
<script src="dwr/util.js" type="text/javascript"></script>
 
<script type="text/javascript">
function sendMessage() {
var text = DWRUtil.getValue("text");
DWRUtil.setValue("text", "");
Chat.addMessage(text, gotMessages);
}
 
function gotMessages(messages) {
var chatlog = "";
for (var data in messages) {
chatlog = "<div>" + messages[data].text +
"</div>" + chatlog;
}
DWRUtil.setValue("chatlog", chatlog);
setTimeout("queryMessage()", 2000);
}
 
function queryMessage() {
Chat.getMessages(gotMessages);
}
</script>
 
</head>
<body>
 
<p>
Your Message:
<input id="text"/>
<input type="button" value="Send"
onclick="sendMessage()"/>
</p>
 
<p>Messages:</p>
<div id="chatlog"></div>
 
</body>
</html>


當List物g傛_時,它成為gotMessages(messages)中的messages物gQ而messages物g中包?Message物g轉換後對應的JavaScript物gQ由於我們已E設定了ConverterQ所以可以用messages[data].text?取得傛_的訊?#8230;

單抓個畫?#8230;




]]>
DWR 入門與應用(二) http://www.aygfsteel.com/jesson2005/articles/111005.html张金?/dc:creator>张金?/author>Mon, 16 Apr 2007 08:28:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111005.htmlhttp://www.aygfsteel.com/jesson2005/comments/111005.htmlhttp://www.aygfsteel.com/jesson2005/articles/111005.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111005.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111005.html假設您要從資料n中查詢出一些字Ԍ然後填寫到表單的下拉選單中?

例如一個示意的JavaE式如下Q?
1
2
3
4
5
6
7
8
package onlyfun.caterpillar;
 
public class Option {
public String[] getOptions() {
// 實際上這些字串是從資料庫中查到的啦…
return new String[] {"良葛?, "毛美?, "c_?};
}
}


傛_的字串陣列,您要填寫C拉選單中Q當Ӟ首先我們要在dwr.xml中開發這個物?#8230;
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">

<dwr>
<allow>
<create creator="new" javascript="OPT">
<param name="class" value="onlyfun.caterpillar.Option"/>
</create>
</allow>
</dwr>


這是我們的E頁…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<script src="option.js" type="text/javascript"></script>
<script src="dwr/interface/OPT.js" type="text/javascript"></script>
<script src="dwr/engine.js" type="text/javascript"></script>
<script src="dwr/util.js" type="text/javascript"></script>
 
</head>
 
<body>
達R: <select id="opts"></select>
</body>
</html>


傛_的字串陣列會填入opts這個select中,我們的option.js如下…
1
2
3
4
5
6
7
8
window.onload = function() {
OPT.getOptions(populate);
};
 
function populate(list){
DWRUtil.removeAllOptions("opts");
DWRUtil.addOptions("opts", list);
}


夠簡單了…不需要解釋了…

看一下結?#8230; 


好啦Q我知道有h在說了,這個程式有夠無?#8230;Dead

改一下!是個不錯的例了,例如連動方塊Q唔Q在Ajax in action中叫啥?Dynamic double comboQ?#8230;

假設一個會d資料庫中查詢資料的JavaE式C意如下Q?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package onlyfun.caterpillar;
 
import java.util.Map;
import java.util.TreeMap;
 
public class Bike {
  private Map<String, String[]> bikes;
  
  public Bike() {
    bikes = new TreeMap<String, String[]>();
    bikes.put("2000", new String[] {"2000 T1", "2000 T2", "2000 T3"});
    bikes.put("2001", new String[] {"2001 A1", "2001 A2"});
    bikes.put("2002", new String[] {"2002 BW1", "2002 BW2", "2002 BW"});
    bikes.put("2003", new String[] {"2003 S320"});
    bikes.put("2004", new String[] {"2004 TA1", "2004 TA2", "2004 TA3"});
  }
  
  public String[] getYears() {
    String[] keys = new String[bikes.size()];
    int i = 0;
    for(String key : bikes.keySet()) {
      keys[i++] = key;
    }
    return keys;
  }
  
  public String[] getBikes(String year) {
    return bikes.get(year);
  }
}


getYears()跟getBkies()分別表示產品的年份跟型號Q這邊用Map模擬Q實際上資料是來自資料n的查詢?

一樣的Q在dwr.xml中設定:
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">

<dwr>
<allow>
<create creator="new" javascript="Bike" scope="application">
<param name="class" value="onlyfun.caterpillar.Bike"/>
</create>
</allow>
</dwr>


我們會有個腳t車q䆾與型號查詢頁面:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Insert title here</title>
<script type='text/javascript' src='dwr/interface/Bike.js'></script>
<script type='text/javascript' src='dwr/engine.js'></script>
<script type='text/javascript' src='dwr/util.js'></script>
<script type='text/javascript' src='bike.js'></script>
</head>
<body onload="refreshYearList();">
  q䆾Q?lt;select id="years" onchange="refreshBikeList();"></select><br/><br/>
  型號Q?lt;select id="bikes"></select><br/>
</body>
</html>


注意Q在選完W一個年份後Q會觸發onchange事gQ接著第二個下拉選單會自動填上應q䆾的型號,而不是按鈕按下,再去取得W二個下拉選單,然後refresh...blah...blah...

bike.js如下…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function refreshYearList() {
Bike.getYears(populateYearList);
}
 
function populateYearList(list){
DWRUtil.removeAllOptions("years");
DWRUtil.addOptions("years", list);
refreshBikeList();
}
 
function refreshBikeList() {
var year = $("years").value;
Bike.getBikes(year, populateBikeList);
}
 
function populateBikeList(list){
DWRUtil.removeAllOptions("bikes");
DWRUtil.addOptions("bikes", list);
}


一樣很單…

看個無聊的畫面…XD




]]>
DWR 入門與應用(一Q?http://www.aygfsteel.com/jesson2005/articles/110998.html张金?/dc:creator>张金?/author>Mon, 16 Apr 2007 08:14:00 GMThttp://www.aygfsteel.com/jesson2005/articles/110998.htmlhttp://www.aygfsteel.com/jesson2005/comments/110998.htmlhttp://www.aygfsteel.com/jesson2005/articles/110998.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/110998.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/110998.htmlJava 開發人員與網頁設ah員的樑 DWR…呃!我懶得寫介?#8230;直接來看看可以做什麼吧Q?#8230;

請先?http://getahead.ltd.uk/dwr/ 下載 dwr.jarQ放到WEB-INF/lib?#8230;

負K處理客戶端請求,並呼叫Java物g的是DWRServletQDWR其實也有些Model 2的味道,只是View的這一層比較弱Q因為放到客戶端的JavaScript應用E式?#8230;

在web.xml中加入DWRServlet…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>
ajaxDWR</display-name>
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
<init-param>
<description>
</description>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
</web-app>


接下來寫個簡單的Hello吧!
1
2
3
4
5
6
7
package onlyfun.caterpillar;
 
public class Hello {
public String hello(String name) {
return "哈囉Q? + name + "Q您的第一個DWRQ?;
}
}


客戶端要呼叫這個Java物gQ傳i它參數Q而後傛_一個字Ԍ客戶端再示這個字Ԍ奇Q其實是要告aDWRServlet這g事,這需要一個dwr.xmlQ?
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
"http://www.getahead.ltd.uk/dwr/dwr10.dtd">

<dwr>
<allow>
<create creator="new" javascript="Hello">
<param name="class" value="onlyfun.caterpillar.Hello" />
</create>
</allow>
</dwr>


creatora定為newQ表CZ用Hello的無參數建構子來生成物gQjavascripta定為HelloQ表C客戶端JavaScriptE式可以使用Hello來呼叫對應的onlyfun.caterpillar.Hello物g?

來寫個客戶端的網頁,當中有一個入欄?#8230;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>W一個DWRE式</title>
<script type='text/javascript' src='dwr/interface/Hello.js'></script>
<script type='text/javascript' src='dwr/engine.js'></script>
<script type='text/javascript' src='dwr/util.js'></script>
<script type='text/javascript' src='hello.js'></script>
</head>
<body>
 
<input id="user" type="text" />
<input type='button' value='哈囉' onclick='hello();' />
 
<div id="result"></div>
 
</body>
</html>


dwr/interface/Hello.js是由DWRServletҎdwr.xml中的a定生成的,engine.js負K客戶端伺服端溝通,util.js是一些好用的JavaScriptE式Q可以讓您少寫很多JavaScript?

hello.js是我們自a的函式Q按下按鈕後Q會呼叫當中的hello()函式Q?
1
2
3
4
5
6
7
8
function hello() {
var user = $('user').value;
Hello.hello(user, callback);
}
 
function callback(msg) {
DWRUtil.setValue('result', msg);
}


${'user'}取得輸入Ƅ位的DOM物gQvalue取得當中的欄位|而後呼叫Hello.hello()Q並value當作參數傳?#8230; i果是呼叫Server端的Hello Java物gQ當i果傛_後,會呼叫JavaScript的callback函式QDWRUtil的setValue()Ҏ會將傛_的msga定i指?id的DOMQ結果就?#8230;啥!AJAX的功能在?#8230;這個而言是發出非同步請求,而回應不用Refresh頁面啦! 



好啦Q這個無聊的Hello DWR可以做啥Q?#8230;XD

已經可以讓您做個簡單的文字提示功能?#8230;像這?#8230;
http://caterpillar.onlyfun.net/Gossip/index.html

把滑鼠指到書的照片上Q會示提示文字Q這些提示文字本n不是存在E頁上的Q而是在Server端,當滑鼠指到書上時Q會用Request objectLQ然後顯C在框框?#8230;

當然Q我的網站只支援PHPQ所以那不是DWR完成的功能,而且我是直接用Request object跟DOML慢刻?#8230;初學者來說已E有些麻煩了…XD

不過Q用DWR可以很單完成這個功?#8230;

先寫個Java別吧!會抓properties檔案中的文字a息Q例?#8230;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package onlyfun.caterpillar;
 
import java.util.ResourceBundle;
 
public class Book {
private ResourceBundle resource;

public Book() {
resource = ResourceBundle.getBundle("book");
}

public String getDescription(String key) {
return resource.getString(key);
}
}


從程式中q道,它會Lbook_zh_TW.properties的資料,這不是重點啦Q只是Java的一個功能,我們要看的是DWRQ不過先把book_zh_TW.properties準備?#8230;
1
2
3
java=Java 學習{記的介?… BlaBla...
spring=Spring 技術手冊的介紹…BlaBla...
ajax=Ajax in action 中文版的介紹…


唔!裏頭是中文字Q自qnative2ascii轉換?#8230;這也不是重點…我們是要看DWR怎麼做到文字提示功能…

一樣的…要開N個Book物gQ在dwr.xml?#8230;
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
"http://www.getahead.ltd.uk/dwr/dwr10.dtd">

<dwr>
<allow>
<create creator="new" javascript="Book" scope="application">
<param name="class" value="onlyfun.caterpillar.Book"/>
</create>
</allow>
</dwr>


scopea定為applicationQ表C這個Book物g在整個應用程式階D都z著?

然後Q客戶端寫個網?#8230;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<script type='text/javascript' src='dwr/interface/Book.js'></script>
<script type='text/javascript' src='dwr/engine.js'></script>
<script type='text/javascript' src='dwr/util.js'></script>
<script type='text/javascript' src='book.js'></script>
<title>個h著/譯作</title>
</head>
<body>
 
<div id="ajax" onmouseover="getBookData(this);"
onmouseout="clearData();"><a
href="http://www.gotop.com.tw/waweb2004/home/home.aspx?pg=HM010X&bn=AXP011800"><small><img
style="border: 0px solid ; width: 80px; height: 110px; float: left;"
alt="Ajax in action 中文? title="Ajax in action 中文?
src="images/ajax_in_action_c.jpg" hspace="10" vspace="2"></small></a></div>
 
<div id="spring" onmouseover="getBookData(this);"
onmouseout="clearData();"><a
href="http://www.gotop.com.tw/waweb2004/home/home.aspx?pg=HM010X&bn=ACL021000"><small><img
style="border: 0px solid ; width: 80px; height: 110px; float: left;"
alt="Spring 技術手? title="Spring 技術手?
src="images/SpringTech_S.jpg" hspace="10" vspace="2"></small></a></div>
 
<div id="java" onmouseover="getBookData(this);"
onmouseout="clearData();"><a
href="http://www.gotop.com.tw/waweb2004/home/home.aspx?pg=HM010X&bn=ACL020931"><small><img
style="border: 0px solid ; width: 80px; height: 110px; float: left;"
alt="Java 學習{記" title="Java 學習{記"
src="images/JavaGossip_Cover_Small.jpg" hspace="10"
vspace="2"></small></a></div>

<br/><br/><br/><br/><br/><br/>

<div id="info"></div>
 
</body>
</html>


重點在於onmouseover跟onmouseoutQ滑鼠移入與Ud時會呼叫的函式,還有最下面的infoQ抓回來的書c介Ҏ攑ֈ當中…

book.js如下Q簡單的?#8230;
1
2
3
4
5
6
7
8
9
10
11
function getBookData(ele) {
Book.getDescription(ele.id, setBookData);
}
 
function setBookData(description) {
DWRUtil.setValue('info', description);
}
 
function clearData() {
DWRUtil.setValue('info', '');
}


E式很簡單,我懶得解釋了…XD

看一下畫面好?#8230;這是滑鼠Ud Ajax in action中文?/u> 上的介紹畫面…



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1186566


[收藏到我的网?/font>]   良葛格发表于 2006q?9?6?20:06:00



特别推荐Q?/div>


]]>dwr?http://www.aygfsteel.com/jesson2005/articles/110975.html张金?/dc:creator>张金?/author>Mon, 16 Apr 2007 07:34:00 GMThttp://www.aygfsteel.com/jesson2005/articles/110975.htmlhttp://www.aygfsteel.com/jesson2005/comments/110975.htmlhttp://www.aygfsteel.com/jesson2005/articles/110975.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/110975.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/110975.html最q?/span>Ajax比较火,全世界都在讨论。于是我也掺和掺和,直接?/span>XMLHttpRequestQ现在的我还没有那个水^。用Echo2或?/span>backbaseQ又感觉那些U?/span>Ajax?/span>framework太重量了。我要的只是一些简单的应用而已。于是寻觅的重点攑֜了一些对xmlhttpRequestq行轻量U包装的代码库上了。于是我扑ֈ?/span>DWRQ?/span>Direct Web RemotingQ?/span>DWR的口hAJAX and XMLHttpRequest made easyQƈ且它也基本上做到了这一炏V它提供了一个友好的框架和一些很有用?/span>JavaScript库,可以让我用vAjax更容易些。详l的信息可以C们的|站http://www.getahead.ltd.uk/dwr/。顺便在介绍一个网站吧Q?/span>http://www.ajaxmatters.com q里也有很多关于Ajax的资源?/span>

 

下面来简单介l一?/span>DWR?/span>

其实在没?/span>XMLHttpRequest?/span>DWR有了,那时它用的是IFrameQ效果很差,所以我看看了就没有?/span>diao它。现在的DWR主要?/span>XMLHttpRequestQ当然也可以选者用IFrameQ但是不推荐?/span>

DWR是个open source softwareQ授权方式是 ASL version 2.0的。现在网站上examples and tutorials做的也不错。我根据这些东西自׃做了一个应用,在本文的后面我会详细讲到?/span>

现在DWR的最新版本是1.0RC1。在我的试用环境相还比较稳定,没有出现什么问题?/span>

DWR本n以一?/span>dwr.jar?/span>jar包存在,它的入口时一?/span>ServletQ?/span>uk.ltd.getahead.dwr.DWRServletQ所以要?/span>web.xml里配|一下就可以了。具体配|看q里http://www.getahead.ltd.uk/dwr/intro.html。比较简单?/span>dwr为我们提供了一?/span>framework帮我们很Ҏ的实?/span>JavaScript?/span>java之间的通信?/span>

 

howitworks.png
我还没有看过
dwr的源码,具体他是怎么实现的我也不太清楚。但大致上肯定是通过xmlhttprequest来调用它?/span>servlet然后把数据用xml打包解包了。其实我觉得q部分到不是dwrl我带来的最方便的地斏V最方便的地方应该是他的那些js的库?/span>

所以下面我要介l一下它的两个重?/span>js对象?/span>

DWREngine Q?/span>engine.js中)Q?/span>DWRUtil (util.js?/span>)?/span>

DWREngine中的Ҏ是基本上是关?/span>XMLHttpRequest的?/span>

下面中介l一?/span>

DWREngine.setErrorHandler(handler)

默认的错误处理时弹出一个对话框Q你可以通过q个Ҏ改变成你需要的表现形式?/span>

DWREngine.setWarningHandler(handler)

改变默认的警告处理Ş?/font>

DWREngine.beginBatch()

Some Remote Function…

DWREngine.endBatch()

当你有几个远E调用要一赯行时Q就要用到这两个Ҏ?/span>

如果不用q两个方法,你就会发C的远E调用ƈ不以你想象的序q行?/span>

DWREngine中还有一些其它的ҎQ我没有用过。你可以通过dwr?/span>js-doc来看。如果通过文档看不懂它是干什么用的,qjs源码Q源码的注释也是比较详细的?/span>

DWRUtil中也有一些很有用的方法。这些方法一般是~写js的辅助方法?/span>

比如setValue?/span>getValue。大多数html标签?/span>value属性,q时你要获取或者设|它的值时q$(“someid”).value可以了。但是有?/span>html标记是没?/span>value属性的Q它的值时在标{中间Q如<span id=”span1”>some value</span>q时你要取或讑֮的值的时候就?/span>DWRUtil.setValue($(“span1”)Q?/span>someValue)。这样你可以在客户端动态的表现一些数据了?/span>

q有很多很好用的ҎQ?/span>dwr的例子中有一些说明,源码中的注释也比较详l?/span>

Dwr׃l到q里吧。下一,我做了个table的例子?br>screen.jpg



]]>
把DWR的配|写到Spring的配|文仉QSpring2 新特?自定义schema初体验) http://www.aygfsteel.com/jesson2005/articles/110973.html张金?/dc:creator>张金?/author>Mon, 16 Apr 2007 07:33:00 GMThttp://www.aygfsteel.com/jesson2005/articles/110973.htmlhttp://www.aygfsteel.com/jesson2005/comments/110973.htmlhttp://www.aygfsteel.com/jesson2005/articles/110973.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/110973.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/110973.html要读懂我q篇文章估计需要一些前期知识:
你要知道Spring是什么,q且要知道Spring已经Z2.0的版本了?br>你要知道DWR是什么,q且要知道DWR也要?.0的版本了?br>
呵呵Q开个玩W?#8230;…。这q头在BlogJava上؜的,估计没几个不知道上面q两个项了?br>
好了Q现在言归正传。DWR本n提供对Spring的支持,可以直接把Spring中的Bean暴露l客L览器的Javascript调用。在dwr.xml中的写法是这LQ?br>
<dwr>
    
<allow>
        
<create creator="spring" javascript="AjaxPortalService">
            
<param name="beanName" value="AjaxPortalService"/>
            
<include method="changeWondowState"/>
            
<include method="changeWorkbenchState"/>
            
<include method="changeWindowOrder"/>
        
</create>
    
</allow>
</dwr>

q样写到也没什么,只是把项目分模块以后Q虽有的配置都写C个dwr.xml文g里面l护h比较ȝQ尤其再遇到版本理中的代码合ƈ。所以曾l我扩展了DWRQ让它可以从多个文gd配置信息。然后每个模块自׃个配|文Ӟ跟着source一赯。这样做也有问题Q就是现在Java应用E序的配|文件太多啦QSpring的配|,WebWork的配|,Hibernate的配|,DWR的配|,再加上一些杂七杂八的xml和properties。看着q些配置文g直要疯掉了?br>
正在此时Qspring2横空ZQ现在你可以把一些配|文件合q到一起了。正好趁此机会体验一下Spring2的自定义schemaҎ?br>
目标Q?br>把DWR的配|写成这P
<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx
="http://www.springframework.org/schema/tx"
    xmlns:aop
="http://www.springframework.org/schema/aop"
    xmlns:dwr
="http://www.devside.org/schema/spring/dwr"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
           http://www.devside.org/schema/spring/dwr http://www.devside.org/schema/spring/dwr.xsd"

    default-autowire
="byName">
    
    
<bean id="departmentDao" class="cn.com.legendapl.hellostruts2.dao.DepartmentDao"/>
    
<bean id="employeeDao" class="cn.com.legendapl.hellostruts2.dao.EmployeeDao"/>
    
<bean id="companyService" class="cn.com.legendapl.hellostruts2.service.CompanyService"/>
    
    
<aop:config>
        
<aop:pointcut id="companyServiceOperation" expression="execution(* cn.com.legendapl.hellostruts2.service.ICompanyService.*(..))" />
        
<aop:advisor advice-ref="txAdvice" pointcut-ref="companyServiceOperation" />
    
</aop:config>    
    
    
<bean id="ajaxCompanyProxy" class="cn.com.legendapl.hellostruts2.ajax.AjaxCompanyProxy"/>
    
    
<dwr:allow id="ajaxCompanyProxyAllow">
        
<dwr:create beanName="ajaxCompanyProxy" javascript="CompanyProxy">
            
<dwr:include method="findEmployeeById"/>
        
</dwr:create>
        
<dwr:convert converter="bean" match="cn.com.legendapl.hellostruts2.entity.*"/>
    
</dwr:allow>
</beans>


重点在这里:
    <dwr:allow id="ajaxCompanyProxyAllow">
        
<dwr:create beanName="ajaxCompanyProxy" javascript="CompanyProxy">
            
<dwr:include method="findEmployeeById"/>
        
</dwr:create>
        
<dwr:convert converter="bean" match="cn.com.legendapl.hellostruts2.entity.*"/>
    
</dwr:allow>

好了现在动手开始做?br>
原理其实很简单,现在看张图。画的不好,敬请原谅Q?br>


spring-dwr.png

从这样图中我们可以看出我们要做如下工作:
1、做一个dwr.xsdQ定义spring配置文g中的dwrq部分配|的schema?br>   要做q个需要有一定xml和xsd的知识,我也是现学现用啦Q?br>

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.devside.org/schema/spring/dwr"
    xmlns:xsd
="http://www.w3.org/2001/XMLSchema"
    xmlns:beans
="http://www.springframework.org/schema/beans"
    targetNamespace
="http://www.devside.org/schema/spring/dwr" 
    elementFormDefault
="qualified"    
    attributeFormDefault
="unqualified">

    
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"/>
    
    
<xsd:element name="allow">
        
<xsd:complexType>
            
<xsd:complexContent>
                
<xsd:extension base="beans:identifiedType">
                    
<xsd:sequence>
                        
<xsd:element name="create" type="createType" minOccurs="0" maxOccurs="unbounded"/>                
                        
<xsd:element name="convert" type="convertType" minOccurs="0" maxOccurs="unbounded"/>                
                    
</xsd:sequence>  
                
</xsd:extension>
            
</xsd:complexContent>
        
</xsd:complexType>
    
</xsd:element>    
    
<xsd:complexType name="createType">        
        
<xsd:sequence>
            
<xsd:element name="auth" type="authType" minOccurs="0" maxOccurs="unbounded"/>
            
<xsd:element name="include" type="includeType" minOccurs="0" maxOccurs="unbounded"/>
            
<xsd:element name="exclude" type="excludeType" minOccurs="0" maxOccurs="unbounded"/>                            
        
</xsd:sequence>
        
<xsd:attribute name="beanName" type="xsd:string" use="required"/>
        
<xsd:attribute name="javascript" type="xsd:string" use="required"/>                                                
    
</xsd:complexType>   
    
    
<xsd:complexType name="convertType">
        
<xsd:attribute name="converter" type="xsd:string" use="required"/>
        
<xsd:attribute name="match" type="xsd:string" use="required"/>
    
</xsd:complexType>  
    
    
<xsd:complexType name="authType">
        
<xsd:attribute name="method" type="xsd:string" use="required"/>
        
<xsd:attribute name="role" type="xsd:string" use="required"/>
    
</xsd:complexType>
    
<xsd:complexType name="includeType">
        
<xsd:attribute name="method" type="xsd:string" use="required"/>
    
</xsd:complexType>
    
<xsd:complexType name="excludeType">
        
<xsd:attribute name="method" type="xsd:string" use="required"/>
    
</xsd:complexType>
</xsd:schema>

2、我们要做一个DWRNamespaceHandler来处理DWR的配|信息,其实里面做一件事把AllowBeanDefinitionParser注册lallow节点。因为我们dwr的配|部分根节点׃个标{allowQ所以我们就做一个用于解析allow标签的AllowBeanDefinitionParser解析器就行。如果我们的根节点还有其他的标签Q同样也要做相应的解析器?br>

public class DWRNamespaceHandler extends NamespaceHandlerSupport {

    
public void init() {
        
//把AllowBeanDefinitionParser注册到allow节点
        registerBeanDefinitionParser("allow"new AllowBeanDefinitionParser());
    }

}

其实隄是做AllowBeanDefinitionParserQ这里你需要一些DOM模型的知识,来操作配|节点的内容。然后根据内容进行处理。在q里我们Q需要做三g事:
   [1]  把配|节点的内容转换成对象模型,即AllowBeanQ其实就是一些POJO|了Q?br>   [2]  把这个AllowBean注册lSpring的ContextQ这一步是可选的。因为我们主要是把这个BeanlDWRQ当焉道给Spring一份也没什么问题?br>   [3] 把这个AllowBean注册到AllowBeanHolder?br>
3、AllowBeanHolder?br>   其实q就是个单的singletonc,整个q行期只有一个实例。它像一个容器,AllowBeanDefinitionParser往里放QDWR的Configuration再从q里取?br>
4、扩展DWR的DefaultConfigurationQ我们做一个SpringConfiguration。DWR的DefaultConfiguration是负责读取配|信息的。我们在其中加入从AllowBeanHolderd配置信息的功能即可?br>
5、扩展DWR的DWRServletQ我们做一个SpringDWRServletQ原来的DWRServlet加蝲的是DefaultConfigurationQ我们的Serlvet加蝲我们自己的SpringConfiguration卛_?br>
6、万事俱备,只欠东风啦。就是让Spring知道我们q了q些Q?br>   在META-INF目录下(如果没有在src目录下创Z个)加入spring.handlers和spring.schemas两个文g?br>   spring.handlers中的内容Q?br>   http\://www.devside.org/schema/spring/dwr=org.devside.core.support.dwr.DWRNamespaceHandler
   spring.schemas中的内容Q?br>   http\://www.devside.org/schema/spring/dwr.xsd=org/devside/core/support/dwr/dwr.xsd
   
  
注意不要写错字哦Q我一开始就写错一个字母,l果怎么调试都不能成功,q以为Spring2有问题呢?br>
ok了,下面我们可以写一个spring的配|文件来试试喽?br>
下面提供两个源码包,一个是spring-dwr的源码,一个是hellosturts2Q一个struts2+spring2+hibernate3.2的例子,其中有用到spring-dwr的例子?br>
Z减小定wQ我把jar都去掉了Qlib目录下提供了一个列表,你可以自己去扄关的jar包?br>
http://www.aygfsteel.com/Files/mstar/HelloStruts2.zip

http://www.aygfsteel.com/Files/mstar/spring-dwr.zip


]]>
dwr?-一个例?l二) http://www.aygfsteel.com/jesson2005/articles/110972.html张金?/dc:creator>张金?/author>Mon, 16 Apr 2007 07:32:00 GMThttp://www.aygfsteel.com/jesson2005/articles/110972.htmlhttp://www.aygfsteel.com/jesson2005/comments/110972.htmlhttp://www.aygfsteel.com/jesson2005/articles/110972.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/110972.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/110972.html阅读全文

]]>
dwr?-一个例?l一) http://www.aygfsteel.com/jesson2005/articles/110968.html张金?/dc:creator>张金?/author>Mon, 16 Apr 2007 07:31:00 GMThttp://www.aygfsteel.com/jesson2005/articles/110968.htmlhttp://www.aygfsteel.com/jesson2005/comments/110968.htmlhttp://www.aygfsteel.com/jesson2005/articles/110968.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/110968.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/110968.html阅读全文

]]>
dwr?-一个例?一)http://www.aygfsteel.com/jesson2005/articles/110966.html张金?/dc:creator>张金?/author>Mon, 16 Apr 2007 07:29:00 GMThttp://www.aygfsteel.com/jesson2005/articles/110966.htmlhttp://www.aygfsteel.com/jesson2005/comments/110966.htmlhttp://www.aygfsteel.com/jesson2005/articles/110966.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/110966.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/110966.html阅读全文

]]>
DWR结DWRUtil? http://www.aygfsteel.com/jesson2005/articles/110957.html张金?/dc:creator>张金?/author>Mon, 16 Apr 2007 07:14:00 GMThttp://www.aygfsteel.com/jesson2005/articles/110957.htmlhttp://www.aygfsteel.com/jesson2005/comments/110957.htmlhttp://www.aygfsteel.com/jesson2005/articles/110957.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/110957.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/110957.html$();

功能:相当?/span>document.getElementById(id);

参数: id?/span>name属性?/span>;

?/span>:

<script>

       Var ele=$(txt_test);

       Var str=DWRUtil.toDescriptiveString(ele,1)

       DWRUtil.debug(str);

</script>

 

DWRUtil.getValue();

功能:获得指定元素value?/span>

参数: id?/span>name属性?/span>;

注意:该函数只能用于有value属性的元素

?/span>:

<script>

       var val=DWRUtil.getValue(“txt_test”);

       DWRUtil.debug(val);

</script>

 

DWRUtil.getValues();

功能:获得一l指定元素的value?/span>;

参数:id?/span>name构成的数l对?/span>

?/span>:

<script>

       Var arr_=DWRUtil.getValues({“txt_name”:null,”txt_pswd”:null});

       Var str=DWRUtil.toDescriptiveString(arr,1)

       DWRUtil.debug(str);

</script>

 

DWRUtil.setValue();

功能:讄指定元素?/span>value?/span>

参数: id?/span>name属性?/span>

<script>

       DWRUtil.setValue(“txt_test”,”wiley”);

</script>

 

 

DWRUtil.setValues();

功能:讄一l指定元素的?/span>

参数: id?/span>name构成的数l对?/span>

?/span>:

<script>

       DWRUtil.setValues({“txt_name”:”wiley”,”txt_pswd”:”wiley”});

</script>

 

DWRUtil.getText();

功能:获得select元素的文本?/span>

参数: id?/span>name属性?/span>

?/span>:

<script>

       Var txt=DWRUtil.getText (“sel_test”);

       Var val=DWRUtil.getValue(“sel_test”);

       DWRUtil.debug(“Text:”+txt+”\tValue:”+val);

</script>

 

DWRUtil.addRows();

功能:指定表格d?/span>

格式:DWRUtil.addRows(id,items, functions);

参数:

W一个参?/span>:table?/span>tbody?/span>id属性?/span>

W二个参?/span>:数组或链?/span>(可能用词不是很适合)

W三个参?/span>:函数链表

 

?/span>1:

 

      

 

             

      

 

 

 

 

 

      

 

 

 

 

 

 

 

 

 

 

 

 

 

主题

<script>

       Var arr_={“wiley’s blog”,”wiley中国”};

       DWRUtil.addRows(“tby_test”,arr_,[function(arr_){return arr_}]);

</script>

 

 

?/span>2:

 

 

      

 

             

             

      

 

 

 

 

 

      

 

 

 

 

 

 

 

 

 

 

 

 

 

名称 |址

<script>

       Var items=[{“name”:”wiley中国”,”add”:”wiley-cn.com”}];

       DWRUtil.addRows(“tby_test”,items,[function(item){return item.name}, function(item){return item.add}]);

</script>

 

DWRUtil.romoveAllRows();

功能:删除指定表格?/span>

参数:table?/span>tbody?/span>id属性?/span>

?/span>

 

      

 

             

             

      

 

 

 

 

 

      

 

 

 

 

 

 

 

 

 

 

 

 

 

名称 |址

<script>

       DWRUtil.romoveAllRows(“tby_test”);//每次d前将原有数据行删?/span>,防止数据重叠

       Var items=[{“name”:”wiley中国”,”add”:”wiley-cn.com”}];

       DWRUtil.addRows(“tby_test”,items,[function(item){return item.name}, function(item){return item.add}]);

</script>

 

DWRUtil.addOptions();

功能:dselect元素?/span>option子元?/span>

格式:DWRUtil.addOption(id,items)?/span>DWRUtil.addOption(id,items,valueProp,textProp);

参数:

W一个参?/span>:select?/span>id?/span>name属性?/span>

W二个参?/span>:数组或链?/span>(填充数据)

W三、四个参?/span>:链表节点的属?/span>,W三个填?/span>value|W四个填?/span>text?/span>

 

例:

<script>

       Var arr_={“wiley”,”wiley中国”};

       DWRUtil.addRows(“sel_test”,arr_);//此时value?/span>text值相?/span>

       DWRUtil.romoveAllOptions(“sel_test”);

       Var items=[{“name”:”wiley中国”,”add”:”wiley-cn.com”}];

       DWRUtil.addRows(“sel_test”,”add”,”name”);//此时value?/span>text不相?/span>

</script>

 

DWRUtil.romoveAllOptions();

功能:删除指定select元素?/span>option子元?/span>

参数:select元素?/span>id?/span>name属性?/span>

?/span>:前面例子有用?/span>

 

DWRUtil.debug();

功能:{h?/span>alert()

?/span>:前面例子有用?/span>

 

DWRUtil.toDescriptiveString();

功能:对象序列化成字W串,主要用于调试

?/span>:前面的例子有用到



]]>
DWR的学习文档(Hello World,cd转换,Spring,Annotation) http://www.aygfsteel.com/jesson2005/articles/110956.html张金?/dc:creator>张金?/author>Mon, 16 Apr 2007 07:12:00 GMThttp://www.aygfsteel.com/jesson2005/articles/110956.htmlhttp://www.aygfsteel.com/jesson2005/comments/110956.htmlhttp://www.aygfsteel.com/jesson2005/articles/110956.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/110956.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/110956.html阅读全文

]]>
用DWR2.0做的一个Server日志查看?/title><link>http://www.aygfsteel.com/jesson2005/articles/110954.html</link><dc:creator>张金?/dc:creator><author>张金?/author><pubDate>Mon, 16 Apr 2007 07:02:00 GMT</pubDate><guid>http://www.aygfsteel.com/jesson2005/articles/110954.html</guid><wfw:comment>http://www.aygfsteel.com/jesson2005/comments/110954.html</wfw:comment><comments>http://www.aygfsteel.com/jesson2005/articles/110954.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jesson2005/comments/commentRss/110954.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jesson2005/services/trackbacks/110954.html</trackback:ping><description><![CDATA[<div id="wmqeeuq" class=postTitle><a class=postTitle2 id=viewpost1_TitleUrl href="http://www.aygfsteel.com/mstar/archive/2007/01/03/Ajax_DWR2_LogViewer.html"><font color=#646464>用DWR2.0做的一个Server日志查看?/font></a> </div> <p>有时候我需要查看已l部|到服务器上的应用程序的日志Q每ơ都要远E登录服务器感觉很麻烦,所以一般我会把log文g的目录用apache做个|站Q这样通过IE可以访问到了。但是有时要看即时输出情况,p不断的F5Q很ȝ。所以就有个xQ不如用DWR2.0的反转Ajax来做个程序,让日志有变化时自动的发送到客户端,q样我一个劲的按F5了?br><br>我下面就把这个程序分享给大家Q希望大家提提意见?br><br>首先是环境:<br>DWR 2.0.rc1<br>Sun JDK 1.5<br><br>先看张运行v来的囑֐Q大家一看就知道q是个什么东西了?br><img height=509 alt=logviewer.png src="http://www.aygfsteel.com/images/blogjava_net/mstar/pics2007/logviewer.png" width=776 border=0><br>你可以制定要监视的log文gQ当然有哪些文g文g可以被监视,你必d服务端的xml配置中文件设|,当然你也可以监视一个目录里的log文gQ这对于而log文g是每天生成一个的情况很有用。你可以讑֮在浏览器上显C的行数Q操作行敎ͼ屏幕会自动滚动。你q可以添加一些过滤器Q过滤掉不想看见的行Q我目前只做了到了过滤掉一些信息,当然如果你有兴趣Q你也再d一些更复杂的过滤器。过滤器的模式是用正则表辑ּ表示的?br><br>下面是点?#8220;开始监?#8221;Q运行后样子<br><img height=598 alt=logviewer2.png src="http://www.aygfsteel.com/images/blogjava_net/mstar/pics2007/logviewer2.png" width=776 border=0><br>如果服务器上的catalina.2006-12-09.log文g发生变化Q客L的浏览器上log昄Z会自动的向上滚动?br><br><br>下面我就大致的介l一下如何用DWR2.0来实现这L功能。在q里介绍的可能不是很详细Q不清楚的地方请看我提供的源码?br><br>先来介绍一下目录结?br>├─lib  -- ~译和测试用的第三方cd<br>├─webapp -- 部v目录<br>├─test -- 试E序<br>├─java -- ȝ?br>└─build.xml -- ant构徏文g<br><br>webapp下的文g和目?br>?nbsp; style.css  -- 样式表文?br>?nbsp; index.html -- ȝ面文?br>?br>├─WEB-INF<br>?nbsp; ?nbsp; web.xml -- 部v配置文g<br>?nbsp; ?nbsp; dwr.xml -- dwr的配|文?br>?nbsp; ?nbsp; conf.xml -- 我们q个应用E序配置文gQ主要是配置log文g<br>?nbsp; ?br>?nbsp; ├─classes <br>?nbsp; ?br>?nbsp; └─lib <br>?br>└─script -- javascript文g<br><br><br>index.html中就是我们上面的囄上能看到的页面元素。其中的控g的事件处理都写在\script\logviewer.js文g中?br></p> <p>当页面加载时执行startPoll()ҎQ复杂开始与服务器的通信Qƈ且把log文g选择框初始化Q把已经dqo器列表显C出来?</p> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">function</span> <span style="COLOR: #000000"> startPoll() {<br>    DWREngine.setActiveReverseAjax(</span> <span style="COLOR: #0000ff">true</span> <span style="COLOR: #000000">);<br><br>    LogManager.getLogFileNames(</span> <span style="COLOR: #0000ff">function</span> <span style="COLOR: #000000"> (data) {<br>        DWRUtil.removeAllOptions(</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">log_file</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">);<br>        DWRUtil.addOptions(</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">log_file</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">, data);<br>    });<br><br>    LogManager.getFilters(</span> <span style="COLOR: #0000ff">function</span> <span style="COLOR: #000000">(data) {<br>        </span> <span style="COLOR: #0000ff">for</span> <span style="COLOR: #000000"> (</span> <span style="COLOR: #0000ff">var</span> <span style="COLOR: #000000"> i </span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000"> </span> <span style="COLOR: #000000">0</span> <span style="COLOR: #000000">; i </span> <span style="COLOR: #000000"><</span> <span style="COLOR: #000000"> data.length; i</span> <span style="COLOR: #000000">++</span> <span style="COLOR: #000000">) {<br>            addFilterDiv(data[i].pattern, data[i].id);<br>        }<br>    });<br>}</span> </div> <p><br>当点?#8220;开始监?#8221;按钮时调用服务端的LogManager的sendҎQ服务端开启监听线E,开始监听做为参C递的文gQ如果文件有变动׃把最q增加的行发送到览器上来?<br></p> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">var</span> <span style="COLOR: #000000"> startWatch </span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000"> </span> <span style="COLOR: #0000ff">function</span> <span style="COLOR: #000000">() {<br>    clearLog();<br>    LogManager.send(DWRUtil.getValue(</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">log_file</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">));<br>}</span> </div> <p><br></p> <p>当点?#8220;l束监听”按钮Q调用LogManager的stop()ҎQ结束掉监听U程?br></p> <p> </p> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">function</span> <span style="COLOR: #000000"> stopWatch() {<br>    LogManager.stop();<br>}</span> </div> <p> </p> <p><br>当点?#8220;清空日志”按钮Q清除mainPanel中的所有子元素</p> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">function</span> <span style="COLOR: #000000"> clearLog() {<br>    </span> <span style="COLOR: #0000ff">var</span> <span style="COLOR: #000000"> mainPanel </span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000"> $(</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">main_panel</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">);<br>    </span> <span style="COLOR: #0000ff">while</span> <span style="COLOR: #000000"> (mainPanel.hasChildNodes()) {<br>        mainPanel.removeChild(mainPanel.firstChild);<br>    }<br>}</span> </div> <p>当点?#8220;dqo?#8221;Q填充输入框Q要求输入做滤器的正则表辑ּQ输入完成后Q要做两件事Q?br>1、LogManager.addFilterҎQ把输入的正则表辑ּ传送给服务端?br>2、把q个正则表达式添加到面上?/p> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">function</span> <span style="COLOR: #000000"> addFilter() {<br>    </span> <span style="COLOR: #0000ff">var</span> <span style="COLOR: #000000"> regex </span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000"> prompt(</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">输入正则表达?/span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">, </span> <span style="COLOR: #000000">""</span> <span style="COLOR: #000000">);<br>    </span> <span style="COLOR: #0000ff">if</span> <span style="COLOR: #000000"> (regex </span> <span style="COLOR: #000000">!=</span> <span style="COLOR: #000000"> </span> <span style="COLOR: #0000ff">null</span> <span style="COLOR: #000000"> </span> <span style="COLOR: #000000">&&</span> <span style="COLOR: #000000"> regex </span> <span style="COLOR: #000000">!=</span> <span style="COLOR: #000000"> </span> <span style="COLOR: #000000">""</span> <span style="COLOR: #000000">) {<br>        LogManager.addFilter(regex, </span> <span style="COLOR: #0000ff">function</span> <span style="COLOR: #000000"> (filterId) {<br>            addFilterDiv(regex, filterId);<br>        });<br>    }<br>}</span> </div> 注意q里Q我们用CDWR的回调模式,在调用服务端ҎLogManager.addFilter成功后我们才调用客户端的addFilterDivҎ把这个输入的正则表达式显C到面上?br><br>如果你够细心的话,应该会发现在q个js文g中有一个叫做addNewLine的方法在index.html中是没有被调用的。这个方法其实是l服务端的LogManager.send函数调用的?br><br>上面q些内容是服务端脚本的主要内容了,其实很简单。主要负责通过DWR与服务端通信和处理页面显C?br><br>下面介绍服务端的核心c:LogManager<br><br>q个cM要就q样几个ҎQ?br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">   </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br>     * 停止监控<br>     </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> stop() {<br>        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (watcher </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">) {<br>            watcher.halt();<br>        }<br>    }<br><br>    </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br>     * 发送log信息<br>     </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> send(String filename) {<br>        WebContext wctx </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> WebContextFactory.get();<br>        </span><span style="COLOR: #0000ff">final</span><span style="COLOR: #000000"> ScriptSession scriptSession </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> wctx.getScriptSession();<br>        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (watcher </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">) {<br>            watcher.halt();<br>        }<br><br>        </span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"> {<br>            watcher </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> LogFileWatcher(filename);<br>            watcher.addListener(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> LogUpdateListener() {<br>                </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> onLogUpdate(List</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> lines) {<br>                    </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (String line : lines) {<br>                        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (checkFilters(line)) {<br>                            ScriptBuffer scriptBuffer </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ScriptBuffer();<br>                            scriptBuffer.appendScript(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">addNewLine(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br>                                    .appendData(line)<br>                                    .appendScript(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>                            scriptSession.addScript(scriptBuffer);<br>                        }<br>                    }<br>                }<br>            });<br>            watcher.start();<br>        } </span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000"> (IOException e) {<br>            ScriptBuffer scriptBuffer </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ScriptBuffer();<br>            scriptBuffer.appendScript(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">addNewLine(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br>                    .appendData(e.getMessage())<br>                    .appendScript(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>            scriptSession.addScript(scriptBuffer);<br>            log.warn(e);<br>        }<br>    }<br><br>    </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br>     * 取得指定的日志文件\?br>     *<br>     * </span><span style="COLOR: #808080">@return</span><span style="COLOR: #008000"> 指定的日志文件\?br>     </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> List</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> getLogFileNames() {<br>        List</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> filenames </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ArrayList</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">></span><span style="COLOR: #000000">();<br>        </span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"> {<br>            XMLConfiguration config </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> getConfiguration();<br>            List logfiles </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> config.getList(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">log-files.file</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>            </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (Object o : logfiles) {<br>                filenames.add((String) o);<br>            }<br>        } </span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000"> (ConfigurationException e) {<br>            log.warn(e);<br>        }<br><br>        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> filenames;<br>    }<br><br>    </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br>     * 取得指定的日志目录下的文?br>     *<br>     * </span><span style="COLOR: #808080">@return</span><span style="COLOR: #008000"> 指定的日志目录下的文?br>     </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> List</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> getLogFileNamesFromDir() {<br>        List</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> filenames </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ArrayList</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">></span><span style="COLOR: #000000">();<br>        </span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"> {<br>            XMLConfiguration config </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> getConfiguration();<br>            String dir </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> config.getString(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">log-dir.dir</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (dir </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">) {<br>                File rootDir </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> File(dir);<br>                </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (rootDir.exists()) {<br>                    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (rootDir.isFile()) {<br>                        filenames.add(rootDir.getPath().replace(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">\\</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">));<br>                    } </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (rootDir.isDirectory()) {<br>                        String patternString </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> config.getString(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">log-dir.filter</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>                        File[] files;<br>                        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (patternString </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">patternString.equals(</span><span style="COLOR: #000000">""</span><span style="COLOR: #000000">)) {<br>                            files </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rootDir.listFiles(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> LogFileFilter(patternString));<br>                        } </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> {<br>                            files </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rootDir.listFiles();<br>                        }<br><br>                        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (File file : files) {<br>                            filenames.add(file.getPath().replace(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">\\</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">));<br>                        }<br>                    }<br>                }<br>            }<br>        } </span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000"> (ConfigurationException e) {<br>            log.warn(e);<br>        }<br><br>        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> filenames;<br>    }<br><br>    </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br>     * d一个过滤器Q返回过滤器的id<br>     </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> addFilter(String regex) {<br>        </span><span style="COLOR: #0000ff">synchronized</span><span style="COLOR: #000000"> (filters) {<br>            Filter filter </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Filter(regex, SequenceGenerator.getInstance().next(), FilterType.INCLUDE);<br>            filters.add(filter);<br>            </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> filter.getId();<br>        }<br><br>    }<br><br>    </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br>     * Ҏid删除一个过滤器<br>     </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> removeFilter(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> id) {<br>        </span><span style="COLOR: #0000ff">synchronized</span><span style="COLOR: #000000"> (filters) {<br>            filters.remove(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Filter(id));<br>        }<br>    }<br><br>    </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br>     * 取得现在所有的qo器列?br>     </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> List</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">Map</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">String, Object</span><span style="COLOR: #000000">>></span><span style="COLOR: #000000"> getFilters() {<br>        List</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">Map</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">String, Object</span><span style="COLOR: #000000">>></span><span style="COLOR: #000000"> result </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ArrayList</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">Map</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">String, Object</span><span style="COLOR: #000000">>></span><span style="COLOR: #000000">();<br>        </span><span style="COLOR: #0000ff">synchronized</span><span style="COLOR: #000000"> (filters) {<br>            </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (Filter filter : filters) {<br>                Map</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">String, Object</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> filterItem </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> HashMap</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">String, Object</span><span style="COLOR: #000000">></span><span style="COLOR: #000000">();<br>                filterItem.put(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">id</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, filter.getId());<br>                filterItem.put(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">pattern</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, filter.getPattern().pattern());<br>                result.add(filterItem);<br>            }<br>        }<br>        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> result;<br>    }</span></div> <br>对于大家都做qJava的朋友来_q些代码应该很容易就能看懂,我就不多说了。大家主要注意一下ScriptSessionc,q个cd是vC要功能的cM?br><br>其中的LogFileWatcher是一个Threadc,它是用来监视log文g的?br><br>SequenceGenerator.java是用来生成过滤器的id的?br><br>LogUpdateListener.java是一个接口,用于实现事g回调的?br><br>然后看一个dwr的配|文?br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">dwr</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>    </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">allow</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">create </span><span style="COLOR: #ff0000">creator</span><span style="COLOR: #0000ff">="new"</span><span style="COLOR: #ff0000"> javascript</span><span style="COLOR: #0000ff">="LogManager"</span><span style="COLOR: #ff0000"> scope</span><span style="COLOR: #0000ff">="session"</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">param </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="class"</span><span style="COLOR: #ff0000"> value</span><span style="COLOR: #0000ff">="org.devside.logviewer.LogManager"</span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br>            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">include </span><span style="COLOR: #ff0000">method</span><span style="COLOR: #0000ff">="send"</span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br>            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">include </span><span style="COLOR: #ff0000">method</span><span style="COLOR: #0000ff">="stop"</span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br>            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">include </span><span style="COLOR: #ff0000">method</span><span style="COLOR: #0000ff">="getLogFileNames"</span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br>            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">include </span><span style="COLOR: #ff0000">method</span><span style="COLOR: #0000ff">="getLogFileNamesFromDir"</span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br>            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">include </span><span style="COLOR: #ff0000">method</span><span style="COLOR: #0000ff">="addFilter"</span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br>            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">include </span><span style="COLOR: #ff0000">method</span><span style="COLOR: #0000ff">="removeFilter"</span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br>            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">include </span><span style="COLOR: #ff0000">method</span><span style="COLOR: #0000ff">="getFilters"</span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">create</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>    </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">allow</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">dwr</span><span style="COLOR: #0000ff">></span></div> <br>q里的配|文件和1.x几乎没什么两P是scope我这里设|成了session范围的。这样就可以多个人同时监视不同的log文g了?br><br>web.xml文g也基本上是老样?br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff"><?</span><span style="COLOR: #ff00ff">xml version="1.0" encoding="UTF-8"</span><span style="COLOR: #0000ff">?></span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">web-app </span><span style="COLOR: #ff0000">id</span><span style="COLOR: #0000ff">="LogViewer"</span><span style="COLOR: #ff0000"> version</span><span style="COLOR: #0000ff">="2.4"</span><span style="COLOR: #ff0000"><br>         xmlns</span><span style="COLOR: #0000ff">="http://java.sun.com/xml/ns/j2ee"</span><span style="COLOR: #ff0000"><br>         xmlns:xsi</span><span style="COLOR: #0000ff">="http://www.w3.org/2001/XMLSchema-instance"</span><span style="COLOR: #ff0000"><br>         xsi:schemaLocation</span><span style="COLOR: #0000ff">="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>    </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">display-name</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000">Web Log Viewer</span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">display-name</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br><br>    </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">servlet</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">description</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000">Direct Web Remoter Servlet</span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">description</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">display-name</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000">DWR Servlet</span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">display-name</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">servlet-name</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000">dwr-invoker</span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">servlet-name</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">servlet-class</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000">org.directwebremoting.servlet.DwrServlet</span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">servlet-class</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">init-param</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">param-name</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000">debug</span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">param-name</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">param-value</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000">true</span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">param-value</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">init-param</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">init-param</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">param-name</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000">pollAndCometEnabled</span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">param-name</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">param-value</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000">true</span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">param-value</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">init-param</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">load-on-startup</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000">1</span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">load-on-startup</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>    </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">servlet</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br><br>    </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">servlet-mapping</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">servlet-name</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000">dwr-invoker</span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">servlet-name</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">url-pattern</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000">/dwr/*</span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">url-pattern</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>    </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">servlet-mapping</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br><br>    </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">welcome-file-list</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">welcome-file</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000">index.html</span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">welcome-file</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br>    </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">welcome-file-list</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">web-app</span><span style="COLOR: #0000ff">></span></div> dwr的包名发生了变化Qƈ且要开启反转ajaxQ就要把<span style="COLOR: #000000">pollAndCometEnabled参数讄为true?br><br>ȝQM来说DWR2.0中的反{ajaxq是很容易用的Q这也是dwr的一贯风|不用知道q多的细节就能容易的实现ajax。dwrl对是Java开发者的首选ajax框架?br>另外我这个程序其实还是ؓ了演C用的,如果惌用户实际开发可能还需要修改,比如安全性上面,性能上面。而性能上面的主要问题是客户端浏览器Q如果服务端的log文gq大Q而浏览器有不能即时的回收内存Q就会造成客户端浏览器内存占用q大而死掉的问题。而服务端׃java的内容回收机制已l比较成熟应该不会有什么问题。我在ie6和firefox2都试q了Qfirefox效果能好一些?br><br>源码下蝲Q?br><a href="http://www.aygfsteel.com/Files/mstar/LogViewer.part1.rar"><u><font color=#6fbc4c>http://www.aygfsteel.com/Files/mstar/LogViewer.part1.rar</font></u></a><br><a href="http://www.aygfsteel.com/Files/mstar/LogViewer.part2.rar"><u><font color=#6fbc4c>http://www.aygfsteel.com/Files/mstar/LogViewer.part2.rar</font></u></a></span> <img src ="http://www.aygfsteel.com/jesson2005/aggbug/110954.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jesson2005/" target="_blank">张金?/a> 2007-04-16 15:02 <a href="http://www.aygfsteel.com/jesson2005/articles/110954.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ajax探烦http://www.aygfsteel.com/jesson2005/articles/110143.html张金?/dc:creator>张金?/author>Thu, 12 Apr 2007 05:06:00 GMThttp://www.aygfsteel.com/jesson2005/articles/110143.htmlhttp://www.aygfsteel.com/jesson2005/comments/110143.htmlhttp://www.aygfsteel.com/jesson2005/articles/110143.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/110143.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/110143.html阅读全文

]]>
GWT入门http://www.aygfsteel.com/jesson2005/articles/110101.html张金?/dc:creator>张金?/author>Thu, 12 Apr 2007 02:46:00 GMThttp://www.aygfsteel.com/jesson2005/articles/110101.htmlhttp://www.aygfsteel.com/jesson2005/comments/110101.htmlhttp://www.aygfsteel.com/jesson2005/articles/110101.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/110101.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/110101.html

面向 Java 开发h员的 Ajax: Google Web Toolkit 入门

developerWorks
文档选项
此作为电子邮件发?src="http://www.ibm.com/i/v14/icons/em.gif"

此作为电子邮件发?/font>

未显C需?JavaScript 的文档选项


拓展 Tomcat 应用

下蝲 IBM 开?J2EE 应用服务?WAS CE 新版?V1.1


U别: 初

??/font>, ?J 族创始h

2006 q?7 ?03 ?/p>

Ajax 被用于创建更加动态和交互性更好的 Web 应用E序。Google Web Toolkit (UGWT) ?Google 推出?Ajax 应用开发包QGWT 支持开发者用Java 语言开?Ajax 应用。本文中作者将介绍如何使用 GWT 开?Ajax 应用的基本方法和步骤?/blockquote>

Ajax?/span>

Ajax?Asynchronous JavaScript and XMLQ以?DHTML {)的羃写,由XHTML、CSS、JavaScript、XMLHttpRequest、XML{技术组合而成Q是当前Web应用开发领域的热门技术,用于创徏更加动态和交互性更好的Web应用E序Q提升用L览体验?/p>

Ajax的核心是JavaScript对象XmlHttpRequest。XmlHttpRequest处理所有服务器通信的对象,是一U支持异步请求的技术。简而言之,XmlHttpRequest使您可以使用JavaScript向服务器提出hq处理响应,而不d用户?/p>

Ajaxq不是本文的中心x点,因此q里不再赘述Q请大家讉K参考资源区的相关链接,了解更多关于Ajax技术和应用斚w的知识?/p>



回页?/font>


Z么选择GWTQ?/span>

众所周知Q即使对于Ajax技术非常熟悉的开发者而言QAjax应用的开发和调试q程也不是一件容易的事情Q更困难的是Q到目前为止Q一直没有出现合适的开发工兯够支持Ajax应用的开发和调试?/p>

与此相反的是QJava语言--企业应用开发的L语言-的开发和调试q程却因为有各种各样开发工L支持而简单的多,而且q样的开发工h们可以免费获得,比如Eclipse、NetBeans?/p>

如果能够应用Java语言开发AjaxQAjax应用开发的最大难?开发工L~失-将q刃而解。这U情况下Q我们就可以既充分利用Java语言的开发优劉K低Ajax应用开发的隑ֺQ加快Ajax应用的开发速度QؓAjax的大规模应用创造可能,又可以充分发挥Ajax技术的优势Q创建更加动态和交互性更好的Web应用E序Q提升用L览体验?/p>

Google Web Toolkit(UGWT)的出Cؓ我们提供了这U可能。GWT是Google推出的Ajax应用开发包Q支持开发者用Java语言开发Ajax应用。GWT框架本n是开源的Q但是GWT中的开发工具仅仅提供开发用LicenseQ不允许分发?/p>

GWT提供了一l基于Java语言的开发包Q这个开发包的设计参考Java AWT包设计,cd名规则、接口设计、事件监听等都和AWT非常cM。熟悉Java AWT的开发者不需要花费多大的力气p够快速的理解GWT开发工具包Q将更多地时间投入到GWT应用的开发过E中?/p>

开发出来的Java应用由GWT开发包提供的编译工L译后声生成对应的、应用了Ajax技术的Web应用QJava应用中出现的、和服务器之间的交互动作被自动生成的异步调用代码所代替?/p>



回页?/font>


GWTҎ?/span>

GWT除了支持应用Java语言开发的应用转化为Ajax应用Q同时提供了更多的高U特性,下面是这些特性的单描q?/p>

1. GWT~译?/p>

GWT~译器是GWT的核心,负责完成Java代码译很Ajax内容的工作。GWT~译器能够翻译Java语言的大部分Ҏ。包括支持Java语言中的基本cd、违例处理等Q支持java.lang包和java.util包中的绝大部分类和接口,支持正则表达式和序列化?/p>

2. 跨^台支?/p>

如果你用GWT中提供的昄lg(比如Button)和组装组?比如VerticalPanel)QGWT~译生成的Ajax应用能够支持大部分的览器和操作pȝQ比如Internet Explorer、Firefox{,也能够支持Linux、Windows{不同操作系l。这是因为GWT最大限度的这些控件翻译成览器内|的cd。比如Buttoncȝ译后生成的是标准HTMLQ?lt;input type="button">?/p>

GWT使用CSS修饰面元素的显C效果。GWT的类中很提供访问页面元素样式属性的ҎQ我们可以直接在CSS文g中通过对应的样式名U来讄面元素的默认显C效果。比如?.gwt-Button { font-size: 150%; } 使用Button元素的默认显C效果?/p>

3. 宿主模式(Hosted Mode)

宿主模式是指我们和没有{换ؓAjax应用的GWT应用交互的状态。当我们开发和调试Ӟ我们׃直处在宿L式下。在q种情况下,Java虚拟Z用GWT内置的浏览器q行GWT应用~译后的class内容Q因此能够提?~码、测试、调?q程的最佳速度?/p>

我们可以q行com.google.gwt.dev.GWTShell启动宿主模式?/p>

4. Web模式(Web Mode)

Web模式是指已经成功转化为Ajax应用的状态,q种状态下Q我们已l开始通过Web方式来访问Ajax应用了?/p>

在Web模式下运行时Q不再需要GWT工具包或者JVM的支持?/p>

5. 命o行工?/p>

GWT工具包中提供了几个非帔R用的小工具来帮助我们更快的建立GWT应用开发环境:projectCreator、applicationCreator、junitCreator?/p>

  • projectCreator
    创徏在Eclipse中开发GWT应用所需要的目基本文g和可选的Ant buildfile文g?
  • applicationCreator
    applicationCreator命o用于创徏基本的HelloWorldQ应用和GWT应用开发环境?
  • junitCreator
    生成junti试代码?

通过上面的内容,我们已经了解了GWT工具集工作的基本原理和主要特性。有些迫不及待了吧,那么p随我一赯入GWT应用开发的q程吧,享受应用Java语言开发Ajax应用带来的简单和便利?/p>

本文中所有的环境准备、实例开发和说明均针对Windows操作q_Q如果用其他的操作pȝQ请Ҏ实际情况q行适当的调整?/p>



回页?/font>


环境准备

1?下蝲和安装JDK1.4.X

GWT工具包的~译需要JDK支持Q因此在安装GWT工具包之前请下蝲和安装合适的JDK。GWT工具支持Java语言1.4版本或者以下版本,因此JDK版本选择JDK1.4.X是比较合适的Q不需要采用最新的JDK5.0或者更高版本?/p>

误问java.sun.com|站上下载安装版本,下蝲后安装到C:/jdk目录下,本书中的后箋内容中将使用%JAVA_HOME%变量来引用这个目录?/p>

您可以根据实际情况将JDK安装CQ意目录下。但是在q行本文中例子的时候,误住将对应?JAVA_HOME%变量替换为您的实际安装目录?/p>

2?下蝲和安装GWT

误?a >http://code.google.com/webtoolkit/下蝲GWT的最新版本,下载的压羃文g解压~到C:/GWT目录下。本书中的后l内容中?GWT_HOME%变量来引用这个目录?/p>

GWT工具包支持不同的操作pȝQ请Ҏ自己的操作系l选择合适的安装包?/p>

您可以根据实际情况将GWT安装CQ意目录下。但是在q行本文中例子的时候,误住将对应?GWT_HOME%变量替换为您的实际安装目录?/p>



回页?/font>


W一个例?Hello WorldQ?/span>

下面的内容中我们介l如何用GWT工具集来完成W一个GWT的例?"Hello WorldQ?Qƈ且将使用GWT~译及将他{化ؓAjax应用Q在览器中完成试?/p>

我们要完成的例子要实现的功能包括Q?/p>

1?在页面上昄一个按?/p>

2?点击该按钮,默认情况下,我们在按钮后面紧跟着昄字符?Hello World!"?/p>

3?如果点击按钮Ӟ"Hello World!"字符串已l显C在览器中Q我们要他隐藏h。我们现在开始用GWT工具集完?Hello WorldQ?例子的开发,下面的步骤是完成"Hello WorldQ?例子开发环境配|、应用开发、编译的基本步骤Q同样适用于其他GWT应用的开发,只是Ҏ实际情况可能有增减?/p>

1?创徏GWT应用开发环?/p>

从上面的GWTҎ部分我们知道,GWT工具包中提供的applicationCreator命o行工具可以帮助我们创建GWT应用开发所需要的环境Q因此我们可以直接用applicationCreator帮助我们完成q项工作?/p>

打开命o行工Pq入C:/根目录下Q执?mkdi"命o创徏新的文g目录HelloWorld?/p>
C:\> mkdir HelloWorld
                        

执行下面的命令将%JAVA_HOME%\bin目录?GWT_HOME%目录加入到PATH路径中?/p>
C:\>set path=%JAVA_HOME%\bin;%GWT_HOME%
                        

请将命o行中?JAVA_HOME%替换为实际环境中JDK的安装目录,?GWT_HOME%替换为GWT工具包的安装目录?/p>

q入新创建的HelloWorld目录Q然后运行applicationCreator命o创徏GWT应用开发环境?/p>

applicationCreator.cmd命o支持的语法如下?/p>

ApplicationCreator [-eclipse projectName] [-out dir] [-overwrite] [-ignore] className 其中最重要的一个参数是classnameQ也是我们创徏的GWT应用中的主Javac,我们q里选择使用org.vivianj.gwt.client.HelloWorld?/p>
C:\HelloWorld>applicationCreator.cmd org.vivianj.gwt.client.HelloWorld
                        

ҎGWT工具包的默认规则QGWT应用中的主JavacL名的最后一D必Lclient。也是_只有xxx.client.Xxxxq样命名的JavacL能被识别为正的GWT应用ȝ?/p>

ApplicationCreator工具q行的时候,屏幕上会打印如下内容?/p>
Created directory C:\HelloWorld\src
                        Created directory C:\HelloWorld\src\org\vivianj\gwt
                        Created directory C:\HelloWorld\src\org\vivianj\gwt\client
                        Created directory C:\HelloWorld\src\org\vivianj\gwt\public
                        Created file C:\HelloWorld\src\org\vivianj\gwt\HelloWorld.gwt.xml
                        Created file C:\HelloWorld\src\org\vivianj\gwt\public\HelloWorld.html
                        Created file C:\HelloWorld\src\org\vivianj\gwt\client\HelloWorld.java
                        Created file C:\HelloWorld\HelloWorld-shell.cmd
                        Created file C:\HelloWorld\HelloWorld-compile.cmd
                        

2?开?Hello WorldQ?例子

使用ApplicationCreator工具的时候,ApplicationCreator工具其实已经帮我们生成了W合Hello World!例子要求的全部内宏Vؓ了不打断W一个例子的演示q程Q我们先单的了解一下ApplicationCreator工具的生成内宏V我们将在将在测试过E后面做出更加详l的分析?/p>

?中显CZApplicationCreator工具执行后生成的目录l构?/p>
? GWT应用开发环?/strong>
?  GWT应用开发环? src=

?中的src\org\vivianj\gwt\client目录中的HelloWorld.java是GWT应用的主c;src\org\vivianj\gwt\public目录中的HelloWorld.html文g是例子的默认面Qsrc\org\vivianj\gwt目录下的HelloWorld.gwt.xml是GWT应用的配|文Ӟ提供GWT应用中页面和ȝ的配|信息;根目录下的HelloWorld-compile.cmd文g用于提供该GWT应用~译成Ajax的命令;根目录下的HelloWorld-shell.cmd文g用于启动宿主模式(Hosted Mode)Q方便测试GWT应用?/p>

3?在宿L式下启动"Hello WorldQ?例子

我们可以直接在命令行中执行HelloWorld-shell.cmd来启动宿L?Hosted Mode)Q运行新创徏?Hello WorldQ?例子?/p>
C:\HelloWorld>HelloWorld-shell.cmd
                        

q个命o启动两个可视化界面QGoogle Web Toolkit Development ShellQ见?Q和GWT内置的GWT应用览器(见图3Q,GWT应用览器中显C?Hello WorldQ?例子的初始界面,如果我们点击界面上的"Click Me"按钮Q按钮后面将会显C?Hello World!"字符Ԍ见图4Q,如果再次单击面上的"Click Me"按钮Q按钮后面的"Hello WorldQ?字符串会消失?/p>
? Google Web Toolkit Development Shellq行界面
?  Google Web Toolkit Development Shellq行界面

? "Hello WorldQ?例子初始q行界面
?  Hello WorldQ例子初始运行界? src=

? "Hello WorldQ?例子-单击"Clieck Me"按钮后的界面
?  Hello WorldQ例?单击Clieck Me按钮后的界面

4?~译"Hello WorldQ?例子

要将GWT应用~译成Ajax应用Q我们可以执行HelloWorld-compile.cmd?/p>
C:\HelloWorld>HelloWorld-compile.cmd
                        

命oq行Ӟ界面上将会显CZ面的内容?/p>
Output will be written into C:\HelloWorld\www\org.vivianj.gwt.HelloWorld
                        Copying all files found on public path
                        Compilation succeeded
                        

其中的第一行显C生成的Ajax应用位于C:\HelloWorld\www\org.vivianj.gwt.HelloWorld目录下?/p>
? "Hello WorldQ?例子~译后的目录l构
?  Hello WorldQ例子编译后的目录结? src=

从上面的图中我们可以看到Q新生成的www目录下有一个名为org.vivianj.gwt.HelloWorld的目录,它的命名规则是GWTȝ全名(org.vivianj.gwt.client.HelloWorld)L其中?client."?/p>

org.vivianj.gwt.HelloWorld目录下的HelloWorld.html文g是"Hello WorldQ?例子对应的页面,?cache.html后缀l尾的文件就?Hello WorldQ?例子中对应的Ajax代码部分Q而gwt.js文g则是GWT提供的、Ajax代码中需要用到的JavaScript公共函数。其他还有些辅助文g?/p>

5?Web模式下测?Hello WorldQ?例子

q行HelloWorld-compile.cmd后,GWT应用已l被~译成Ajax应用了,不再依赖于JDK和GWT环境Q而仅仅依赖于览器?/p>

我们打开IE览器,打开C:\HelloWorld\www\org.vivianj.gwt.HelloWorld\HelloWorld.html文gQ就可以看到"Hello WorldQ?例子在Web模式下的q行效果Q见?Q,单击面上的"Click Me"按钮Q按钮后面会出现"Hello WorldQ?字符Ԍ见图7Q,如果再次单击面上的"Click Me"按钮Q按钮后面的"Hello WorldQ?字符串会消失?/p>
? Web模式下运?HelloWorldQ?例子的默认效?/strong>
?  Web模式下运?HelloWorldQ例子的默认效果

? Web模式下运?HelloWorldQ?例子-单击"Click Me"按钮后的效果
?  Web模式下运?HelloWorldQ例?单击 Click Me按钮后的效果




回页?/font>


实例详细分析

上面的步骤中Q我们已l完成第一个GWT应用的编译和试Q下面我们来详细的介l一下GWT应用开发过E中涉及的几个文Ӟ昄面HelloWorld.html、主cHelloWorld和配|文件HelloWorld.gwt.xml?/p>

1. 昄面HelloWorld.html

GWT应用中的HTML内容必须存放在public目录下,public目录的全路径?org\vivianj\gwt\ublic"Q是主cHelloWorld的包?org.vivianj.gwt.client"中的client替换?public"后Ş成的目录l构?/p>

我们主要介lHelloWorld.html中和GWT相关的内容,HelloWorld.html文g的全部内容见清单1?/p>
24.    <meta name='gwt:module' content='org.vivianj.gwt.HelloWorld'>
                        

在HelloWorld.html文g的第24行,我们使用meta标签指定了本面和GWT模块" org.vivianj.gwt.HelloWorld"之间的联p,meta标签的name属性是不变的,而content属性则是GWTȝ全名(org.vivianj.gwt.client.HelloWorld)L其中?client."后的l果?/p>
40.	    <script language="javascript" src="gwt.js"></script>
                        

在HelloWorld.html文g的第40行,我们使用script标记引入GWT工具提供的默认函数库。根据HTML语言的规定,我们可以选择?lt;head></head>之间加入q行代码Q也可以选择?lt;body></body>之间加入q段代码。GWT?lt;head></head>之间加入q行代码Q以便获得稍微快一些的起动速度?/p>
56.	<td id="slot1"></td><td id="slot2"></td>
                        

在HelloWorld.html文g的第56行,我们使用td标签定义了两个相ȝ表格单元|他们分别命名?slot1"?slot2"Q根?HelloWorld!"例子的要求,名ؓ"slot1"的单元格中应该显C按钮,而名?slot2"的单元格中则Ҏ情况军_昄"HelloWorld!"字符串或者不昄M内容?/p>

我们在ȝHelloWorld.java的源代码中用RootPanel.get("slot1")来获得对该单元格的引用,请参考下面的"ȝHelloWorld"部分的说明?/p>
43.	<iframe id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe>
                        

在HelloWorld.html的第43行,我们使用iframe标签来设|当前页支持历史功能Qiframe的属性必d上面的内容保持一_否则不会vCQ何效果?/p>
清单1 src\org\vivianj\gwt\public\public\HelloWorld.html
1.	<html>
                        2.		<head>
                        3.
                        4.			<!--                                           -->
                        5.			<!-- Any title is fine                         -->
                        6.			<!--                                           -->
                        7.			<title>Wrapper HTML for HelloWorld</title>
                        8.
                        9.			<!--                                           -->
                        10.			<!-- Use normal html, such as style            -->
                        11.			<!--                                           -->
                        12.			<style>
                        13.				body,td,a,div,.p{font-family:arial,sans-serif}
                        14.				div,td{color:#000000}
                        15.				a:link,.w,.w a:link{color:#0000cc}
                        16.				a:visited{color:#551a8b}
                        17.				a:active{color:#ff0000}
                        18.			</style>
                        19.
                        20.			<!--                                           -->
                        21.			<!-- The module reference below is the link    -->
                        22.			<!-- between html and your Web Toolkit module  -->
                        23.			<!--                                           -->
                        24.			<meta name='gwt:module' content='org.vivianj.gwt.HelloWorld'>
                        25.
                        26.		</head>
                        27.
                        28.		<!--                                           -->
                        29.		<!-- The body can have arbitrary html, or      -->
                        30.		<!-- you can leave the body empty if you want  -->
                        31.		<!-- to create a completely dynamic ui         -->
                        32.		<!--                                           -->
                        33.		<body>
                        34.
                        35.			<!--                                            -->
                        36.			<!-- This script is required bootstrap stuff.   -->
                        37.			<!-- You can put it in the HEAD, but startup    -->
                        38.			<!-- is slightly faster if you include it here. -->
                        39.			<!--                                            -->
                        40.			<script language="javascript" src="gwt.js"></script>
                        41.
                        42.			<!-- OPTIONAL: include this if you want history support -->
                        43.			<iframe id="__gwt_historyFrame"
                        style="width:0;height:0;border:0"></iframe>
                        44.
                        45.			<h1>HelloWorld</h1>
                        46.
                        47.			<p>
                        48.			This is an example of a host page for the HelloWorld application.
                        49.			You can attach a Web Toolkit module to any HTML page you like,
                        50.			making it easy to add bits of AJAX functionality to existing
                        pages
                        51.			without starting from scratch.
                        52.			</p>
                        53.
                        54.			<table align=center>
                        55.				<tr>
                        56.					<td id="slot1"></td><td
                        id="slot2"></td>
                        57.				</tr>
                        58.			</table>
                        59.		</body>
                        60.	</html>
                        

2. ȝHelloWorld

ȝHelloWorld必须l承自com.google.gwt.core.client.EntryPointc,q且覆盖其public void onModuleLoad()Ҏ?/p>

在onModuleLoad()Ҏ中,我们使用GWT中提供的默认昄lg(比如Button)和组装组?比如VerticalPanel)来设计需要显C的界面Q所有这些组仉位于com.google.gwt.user.client.ui包下面。这些组件的命名规则和Java AWT的命名规则基本类|使用方式也和AWT的基本一_不过GWT中提供了不少的新l徏可供选择Q比如可以直接用VerticalPanel来实现垂直方向的布局理?/p>

HelloWorld.java中的19?0行,声明了Button和Label两个昄lg?/p>
19.    final Button button = new Button("Click me");
                        20.    final Label label = new Label();
                        

onModuleLoad()Ҏ中,我们需要把生成的显C组件或者组装组建加入到昄面的对应显C区域。首先,我们需要在面上用id属性ؓ昄区域指定唯一的名U?参见清单1中的56?。com.google.gwt.user.client.ui.RootPanel的静态方法get可以Ҏ传入的字W串参数Q参数值就是显C区域的id属性)获取面上对应的昄区域?/p>

HelloWorld.java?6?7行,׃用了RootPanel的getҎ分别获得面上id?slot1"?slot2"的显C区域,然后调用addҎ生成的Button和Label对象加入到显C区域中?/p>
36.    RootPanel.get("slot1").add(button);
                        37.    RootPanel.get("slot2").add(label);
                        

Ajax最重要的功能就是ؓ用户提供更好的交互体验,GWT中用和AWT中相同的事g监听机制完成客户端事件监听,GWT中支持的Listener接口包括ChangeListener、ClickListener{。我们可以通过各种各样的Listener接口获得用户界面上所发生的动作,通过处理q些动作来完成对应业务逻辑?/p>

HelloWorld.java中的W?2行~29行的内容实C一个ClickListender接口Qƈ且提供了对应的onClickҎ实现Q用于处理按钮点d的业务逻辑Q判断是否需要显C?Hello World!"字符ԌQ然后调用Button对象的addClickListenerҎ增加监听器?/p>
22.    button.addClickListener(new ClickListener() {
                        23.          public void onClick(Widget sender) {
                        24.            if (label.getText().equals(""))
                        25.              label.setText("Hello World!");
                        26.            else
                        27.              label.setText("");
                        28.          }
                        29.    });
                        

HelloWorldcȝ全部源代码内容见清单2?/p>
清单2 src\org\vivianj\gwt\client\HelloWorld.java
1.	package org.vivianj.gwt.client;
                        2.
                        3.	import com.google.gwt.core.client.EntryPoint;
                        4.	import com.google.gwt.user.client.ui.Button;
                        5.	import com.google.gwt.user.client.ui.ClickListener;
                        6.	import com.google.gwt.user.client.ui.Label;
                        7.	import com.google.gwt.user.client.ui.RootPanel;
                        8.	import com.google.gwt.user.client.ui.Widget;
                        9.
                        10.	/**
                        11.	 * Entry point classes define <code>onModuleLoad()</code>.
                        12.	 */
                        13.	public class HelloWorld implements EntryPoint {
                        14.
                        15.	  /**
                        16.	   * This is the entry point method.
                        17.	   */
                        18.	  public void onModuleLoad() {
                        19.	    final Button button = new Button("Click me");
                        20.	    final Label label = new Label();
                        21.
                        22.	    button.addClickListener(new ClickListener() {
                        23.	      public void onClick(Widget sender) {
                        24.	        if (label.getText().equals(""))
                        25.	          label.setText("Hello World!");
                        26.	        else
                        27.	          label.setText("");
                        28.	      }
                        29.	    });
                        30.
                        31.	    // Assume that the host HTML has elements defined whose
                        32.	    // IDs are "slot1", "slot2".  In a real app, you probably would not want
                        33.	    // to hard-code IDs.  Instead, you could, for example, search for all
                        34.	    // elements with a particular CSS class and replace them with widgets.
                        35.	    //
                        36.	    RootPanel.get("slot1").add(button);
                        37.	    RootPanel.get("slot2").add(label);
                        38.	  }
                        39.	}
                        

3. 配置文gHelloWorld.gwt.xml

配置文g中包括两个元素。Inherits元素地设|GWT应用的承信息,而entry-point元素的class属性则用于讄讄GWT应用的主cR?/p>
清单3 src\org\vivianj\gwt\HelloWorld.gwt.xml
1.	<module>
                        2.
                        3.		<!-- Inherit the core Web Toolkit stuff.                  -->
                        4.		<inherits name='com.google.gwt.user.User'/>
                        5.
                        6.		<!-- Specify the app entry point class.                   -->
                        7.		<entry-point class='org.vivianj.gwt.client.HelloWorld'/>
                        8.
                        9.	</module>
                        





回页?/font>


l束?/span>

Ajax是当前热门的Web应用开发技术,Java是企业应用开发中的主技术,GWT框架这两种技术合二ؓ一Q是我们能够应用Java语言来开发AjaxQ在保留Ajax技术的优点基础上,解决了Ajax应用开发、调试困隄~点?/p>

本文中介l了GWT的基本知识、主要特性,提供?HelloWorldQ?例子说明使用Java和GWT框架开发Ajax应用的开发、编译、测试过E,q且通过?HelloWorldQ?例子中涉及文件的分析Q讲解了使用GWT框架开发Ajax应用的技术细节和U束条g?/p>



回页?/font>


下蝲资源



参考资?

学习

获得产品和技?/strong>
  • JDK 下蝲地址Q?a >http://java.sun.com

  • GWT 下蝲地址Q?a >http://code.google.com/webtoolkit/


讨论


关于作?/span>

 

肖菁Q?a >?J 族创始hQ开源项?a >BuildFileDesigner?a >V-Security 创始人,Open Source 推广人,主要研究 J2EE ~程技术、Web Service 技术以及他们在 WebSphere、WebLogic?Apache q_上的实现Q拥?IBM ?Developing With Websphere Studio 证书?/p>



]]>
վ֩ģ壺 | | ³ɽ| Ӧ| ͬ| | | ƺ| ¡| ԭ| ԭ| IJ| α| | | | | | | ˳| | | | Ӣ| | ֻ| | | | е| | | | | ն| ͤ| ƽɽ| ³ƶ| | | |