dwr反推技术
http://tsunzhang.iteye.com/blog/1447787
DWR2.x的推技術
DWR2.x的推技術也叫DWR Reverse Ajax(逆向Ajax)主要是在BS架構中,從服務器端向多個瀏覽器主動推數據的一種技術。在DWR所開的線程中使用Reverse Ajax時,通過WebContextFactory.get()獲取WebContext對象,進而獲取腳本Session。在DWR之外使用Reverse Ajax時,就要用到ServerContext,在Spring環境中要得到ServerContext,就需要用到Spring的ServletContextAware接口。
一、Reverse Ajax的實現有3種方式:
?? ? ?DWR的逆向Ajax主要包括兩種模式:主動模式和被動模式。其中主動模式包括polling和comet兩種,被動模式只有piggyback這一種。
?? ? 1、piggyback方式
?? ? ? ? ? 這是默認的方式。
?? ? ? ? ? 如果后臺有什么內容需要推送到前臺,是要等到那個頁面進行下一次ajax請求的時候,將需要推送的內容附加在該次請求之后,傳回到頁面。只有等到下次請求頁面主動發起了,中間的變化內容才傳遞回頁面。
?? ? ?2、comet方式
?? ? ? ? ? 當服務端建立和瀏覽器的連接,將頁面內容發送到瀏覽器之后,對應的連接并不關閉,只是暫時掛起。如果后面有什么新的內容需要推送到客戶端的時候直接通過前面掛起的連接再次傳送數據。服務器所能提供的連接數目是一定的,在大量的掛起的連接沒有關閉的情況下,可能造成新的連接請求不能接入,從而影響到服務質量。
?? ? ?3、polling方式
?? ? ? ? ? 由瀏覽器定時向服務端發送ajax請求,詢問后臺是否有什么內容需要推送,有的話就會由服務端返回推送內容。這種方式和我們直接在頁面通過定時器發送ajax請求,然后查詢后臺是否有變化內容的實現是類似的。只不過用了dwr之后這部分工作由框架幫我們完成了。
二、使用DWR的推技術的步驟
?? ? 1、在web.xml文件中增加以下配置信息
Xml代碼??
?
?<!-- 開始DWR配置 -->
?<servlet>
??????? <servlet-name>dwr-invoker</servlet-name>
??????? <!--
??????? <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
??????? -->
??????? <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
??????? <init-param>
??????????? <param-name>debug</param-name>
??????????? <param-value>true</param-value>
??????? </init-param>
??????? <!-- dwr反轉 -->
??????? <!-- 1、piggyback方式??
??????? ?這是默認的方式。??
??????? ?如果后臺有什么內容需要推送到前臺,是要等到那個頁面進行下一次ajax請求的時候,將需要推送的內容附加在該次請求之后,傳回到頁面。??
??????? ?只有等到下次請求頁面主動發起了,中間的變化內容才傳遞回頁面。??
??????? ?2、comet方式??
??????? ?當服務端建立和瀏覽器的連接,將頁面內容發送到瀏覽器之后,對應的連接并不關閉,只是暫時掛起。如果后面有什么新的內容需要推送到客戶端的時候直接通過前面掛起的連接再次傳送數據。??
??????? ?服務器所能提供的連接數目是一定的,在大量的掛起的連接沒有關閉的情況下,可能造成新的連接請求不能接入,從而影響到服務質量。??
??????? ?3、polling方式??
??????? ?由瀏覽器定時向服務端發送ajax請求,詢問后臺是否有什么內容需要推送,有的話就會由服務端返回推送內容。這種方式和我們直接在頁面通過定時器發送ajax請求,然后查詢后臺是否有變化內容的實現是類似的。只不過用了dwr之后這部分工作由框架幫我們完成了。??
??????? -->
??????? <!-- DWR默認采用piggyback方式 -->
??????? <!-- 使用polling和comet的方式 -->
??????? <init-param>
??????? ?<param-name>pollAndCometEnabled</param-name>
??????? ?<param-value>true</param-value>
??????? </init-param>
??????? <!-- comet方式 -->
??????? <!--??????
??????? ?<init-param>????
??????? ?<param-name>activeReverseAjaxEnabled</param-name>????
??????? ?<param-value>true</param-value>????
??????? ?</init-param>????
??????? -->
??????? <!-- polling方式:在comet方式的基礎之上,再配置以下參數 -->
??????? <!--??????
??????? ?<init-param>????
??????? ?<param-name>org.directwebremoting.extend.ServerLoadMonitor</param-name>????
??????? ?<param-value>org.directwebremoting.impl.PollingServerLoadMonitor</param-value>????
??????? ?</init-param>????
??????? -->
??????? <!-- 毫秒數。頁面默認的請求間隔時間是5秒 -->
??????? <!--??????
??????? ?<init-param>????
??????? ?<param-name>disconnectedTime</param-name>????
??????? ?<param-value>60000</param-value>??????
??????? ?</init-param>????
??????? -->
??????? <init-param>
??????? ?<param-name>crossDomainSessionSecurity</param-name>
??????? ?<param-value>false</param-value>
??????? </init-param>
??????? <load-on-startup>1</load-on-startup>
?</servlet>
?<servlet-mapping>
??<servlet-name>dwr-invoker</servlet-name>
??<url-pattern>/dwr/*</url-pattern>
?</servlet-mapping>
?<listener>
??<listener-class>
???org.directwebremoting.servlet.EfficientShutdownServletContextAttributeListener
??</listener-class>
?</listener>
?<listener>
??<listener-class>
???org.directwebremoting.servlet.EfficientShutdownServletContextListener
??</listener-class>
?</listener>
?<!-- 結束DWR配置 -->
?
2、在dwr.xml中增加以下配置信息
Xml代碼
?
<?xml version="1.0" encoding="UTF-8"?>?
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr//dwr20.dtd">
<dwr>?
??? <allow>?
??? ?<create creator="new" javascript="DWRAction">
? ???<param name="class" value="com.tcps.action.DwrActionTest"/>
? ???<include method="DwrTest"/>
? ???<include method="sessionDestory"/>
??</create>
???????
??????? <create creator="new" javascript="DWRReverse">
????? ??<param name="class" value="com.tcps.action.DWRReverse" />
??????? </create>
???????
??????? <convert converter="bean" match="com.tcps.model.User">
??????????? <param name="include" value="username,password" />
??????? </convert>
??? </allow>
</dwr>
?
3、pojo類User的源碼
Java代碼
?
public class User implements java.io.Serializable {
??? // Fields???
???? private Integer id;
???? private String username;
???? private String password;
???? private String age;
???? private String tel;
???? private String sessionid;
??? // Constructors
??? /** default constructor */
??? public User() {
??? }
?/** minimal constructor */
??? public User(Integer id, String username, String password) {
??????? this.id = id;
??????? this.username = username;
??????? this.password = password;
??? }
???
??? /** full constructor */
??? public User(Integer id, String username, String password, String age, String tel, String sessionid) {
??????? this.id = id;
??????? this.username = username;
??????? this.password = password;
??????? this.age = age;
??????? this.tel = tel;
??????? this.sessionid = sessionid;
??? }
??? @Override
??? public String toString(){
?????? return this.username + this.password;
??? }
??? // Property accessors
??? public Integer getId() {
??????? return this.id;
??? }
???
??? public void setId(Integer id) {
??????? this.id = id;
??? }
??? public String getUsername() {
??????? return this.username;
??? }
???
??? public void setUsername(String username) {
??????? this.username = username;
??? }
??? public String getPassword() {
??????? return this.password;
??? }
???
??? public void setPassword(String password) {
??????? this.password = password;
??? }
??? public String getAge() {
??????? return this.age;
??? }
???
??? public void setAge(String age) {
??????? this.age = age;
??? }
??? public String getTel() {
??????? return this.tel;
??? }
???
??? public void setTel(String tel) {
??????? this.tel = tel;
??? }
?public String getSessionid() {
??return sessionid;
?}
?public void setSessionid(String sessionid) {
??this.sessionid = sessionid;
?}
?
?
4、DWRReverse類源碼
Java代碼??
public class DWRReverse extends AbstractAction {
??? public static WebContext wctx = null;
??? public static void sendMessage(User monitor) {
??????? if (wctx == null) {
??????????? wctx = WebContextFactory.get();
??????? }
??????? ScriptBuffer script = new ScriptBuffer();
??????? //執行js 方法
??????? if (monitor != null) {
??????????? StringBuffer sb = new StringBuffer();
??????????? sb.append(monitor.getId()).append(",");
??????????? sb.append(monitor.getUsername()).append(",");
??????????? sb.append(monitor.getPassword()).append(",");
??????????? sb.append(monitor.getAge()).append(",");
??????????? sb.append(monitor.getTel());
??????????? script.appendScript("receiveMessages('").appendData(sb.toString())
??????????????????? .appendScript("');");
??????? }
??????? ServerContext sctx = ServerContextFactory.get(wctx.getServletContext());
??????? Collection<ScriptSession> scriptSessions = sctx.getScriptSessionsByPage(wctx.getCurrentPage());
??????? Util util = new Util(scriptSessions);
??????? //可以設置樣式等??
??????? // util.setStyle("test", "display", "none");??
??????? for (ScriptSession session : scriptSessions) {
??????????? session.addScript(script);
??????? }
??? }
}
?
5、JSP頁面源碼
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
? <head>
??? <base href="<%=basePath%>">
???
??? <title>My JSP 'dwrReverse.jsp' starting page</title>
??? <script type='text/javascript' src='<%=basePath%>/dwr/interface/DWRReverse.js'></script>
??? <script type='text/javascript' src='<%=basePath%>/dwr/engine.js'></script>
??? <script type='text/javascript' src='<%=basePath%>/dwr/util.js'></script>
???
?<meta http-equiv="pragma" content="no-cache">
?<meta http-equiv="cache-control" content="no-cache">
?<meta http-equiv="expires" content="0">???
?<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
?<meta http-equiv="description" content="This is my page">
?<!--
?<link rel="stylesheet" type="text/css" href="styles.css">
?-->
?<script type="text/javascript">
??function getData(){??
??????? ?DWRReverse.sendMessage(null);??
??????? }????
??????? function receiveMessages(message) {
???????? var msg = eval("("+message+")");
???????? var temp? = msg.split(",");
???????? var username = temp[1];
???????? var password = temp[2];
???????? var age = temp[3];
???????? var tel = temp[4];
???????? var newRow = document.getElementById('tableData').insertRow(2);
???????? var cell0 = newRow.insertCell(0);
???????? var cell1 = newRow.insertCell(1);
???????? var cell2 = newRow.insertCell(2);
???????? var cell3 = newRow.insertCell(3);
???????? cell0.innerHTML = username;
???????? cell1.innerHTML = password;
???????? cell2.innerHTML = age;
???????? cell3.innerHTML = tel;
??????? }
?</script>
? </head>
? <!-- 注:這個是要在使用reverse-ajax的頁面必須的 -->
?<body οnlοad="dwr.engine.setActiveReverseAjax(true);getData();">
??<div align="center">
???<table title=用戶表 class="list" align="center" id="tableData">
????<tr id="titleData">
?????<td colspan="4">
??????用戶表
?????</td>
?????<td colspan="1" οnclick="getData()" style="size:10px">
??????<a href="#"></a>
?????</td>
????</tr>
????<tr id="headData" bgcolor="#fffce7" style="color:#968054">
?????<td width="9%">
??????用戶名
?????</td>
?????<td width="20%">
??????密碼
?????</td>
?????<td width="33%">
??????年齡
?????</td>
?????<td width="22%">
??????電話
?????</td>
????</tr>
???</table>
??</div>
?</body>
</html>
?
最后,為了測試,后臺實現定時器:
public class SampleTask extends TimerTask {
??? private ServletContext context;
??? private static boolean isRunning = false;
??? public SampleTask(ServletContext context) {
??????? this.context = context;
??? }
??? @Override
??? public void run() {
??????? // TODO Auto-generated method stub
??????? if (!isRunning) {
??????????? isRunning = true;
??????????? System.out.println("開始執行指定任務");
??????????? if (DWRReverse.wctx != null) {
??????????????? User user = new User(1, "tom", "123456", "10", "13909876543", "");
??????????????? DWRReverse.sendMessage(user);
??????????? }
??????????? isRunning = false;
??????????? // context.log("指定任務執行結束");
??????? } else {
??????????? // context.log("上一次任務執行還未結束");
??????? }
??? }
}
?
總結
- 上一篇: Apache Tomcat 5.5 Se
- 下一篇: TestNG 使 Java 单元测试轻而