DWR(Direct Web Remoting)是一個用於改善web頁面與Java類交互的遠程服務器端Ajax開源框架,可以幫助開發人員開發包含AJAX技術的網站。它可以允許在瀏覽器裏的代碼使用運行在WEB服務器上的JAVA函數,就像它就在瀏覽器裏一樣。
DWR是一個RPC庫,可以很容易地從JavaScript調用Java函數並從Java調用JavaScript函數(也稱爲反向Ajax)
DWR由兩個主要部分組成:
- 在服務器上運行的Java Servlet,它處理請求並將響應發送回瀏覽器。
- JavaScript在瀏覽器中運行,可以發送請求並可以動態更新網頁。
DWR通過基於Java類動態生成Javascript來工作。代碼執行一些Ajax使其感覺神奇執行在瀏覽器上發生,但實際上服務器正在執行代碼,DWR正在編組數據前後。
這種從Java到JavaScript的遠程處理功能的方法使DWR用戶感覺非常像傳統的RPC機制,如RMI或SOAP,其好處是它可以在Web上運行而無需Web瀏覽器插件。
案例分析
demo下載地址:https://download.csdn.net/download/u012401711/10561121
首先我們看搭建的過程
官網下載dwr的jar包和相關的js文件
將dwr.jar引入工稱中,將engine.js和util.js放入到工程的靜態文件區(隨意放置),創建一個dwr.xml文件和web.xml同級
首先說一下web.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>dwr-demo</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<param-name>crossDomainSessionSecurity</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>allowScriptTagRemoting</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>classes</param-name>
<param-value>java.lang.Object</param-value>
</init-param>
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>initApplicationScopeCreatorsAtStartup</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>maxWaitAfterWrite</param-name>
<param-value>3000</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>logLevel</param-name>
<param-value>WARN</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/static/dwr/*</url-pattern>
</servlet-mapping>
</web-app>
dwr就是通過servlet-mapping地址映射去執行相應的servlet邏輯代碼,注意映射的地址就是上面提到的engine.js和util.js所在文件的地址。
<?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>
<!-- Reverse Ajax Stock push Demo Config <create creator="new" javascript="StocksPusher">
<param name="class" value="com.test.dwr.servlet.Test"/> </create> <convert
converter="bean" match="com.test.dwr.bean.Message"> <param name="include"
value="id,context" /> </convert> -->
<create creator="new" javascript="RequestPush">
<param name="class" value="cn.gumx.common.dwr.RequestPush" />
</create>
</allow>
</dwr>
dwr.xml的內容,class類就是我們需要編寫的Java類,其中javaacript就是後面提到jsp頁面引入的js的名稱。
<!-- dwr推送 strat -->
<script type='text/javascript' src='${pageContext.request.contextPath}/static/dwr/engine.js'></script>
<script type='text/javascript' src='${pageContext.request.contextPath}/static/dwr/util.js'></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/dwr/interface/RequestPush.js"></script>
<!-- dwr推送 end -->
頁面引入的js中上面那兩個文件是存在的第三個文件則沒有,這個就會生成的js名稱就是在dwr.xml中提到的,文件夾路徑固定的在dwr靜態目錄後面加上interface。
編寫Java類
public class RequestPush{
public static Map<Object,String> map = new HashMap<Object,String>();
public void onPageLoad(String flag) {
//ScriptSession每個頁面都存在一個
ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
//如果一個頁面存在多個推送模塊,可以使用,隔開
if(map.containsKey(scriptSession)){
String value = map.get(scriptSession);
map.put(scriptSession, value+","+flag);
}else{
map.put(scriptSession, flag);
}
scriptSession.setAttribute("flag", map);
DwrScriptSessionManagerUtil dwrScriptSessionManagerUtil = new DwrScriptSessionManagerUtil();
try {
dwrScriptSessionManagerUtil.init();
System.out.println("----dwrScriptSessionManagerUtil--初始化完成---");
} catch (ServletException e) {
e.printStackTrace();
System.out.println("----dwrScriptSessionManagerUtil--初始化失敗---");
}
}
}
裏面的方法名可以隨意定義,裏面我做了一些業務處理。這裏面的方法就是相當於頁面要去訂閱消息,就如訂報紙有很多種每個人訂閱的類型不同,我們首先要告訴服務器我要訂閱什麼類型的數據,服務器才能將你需要的數據推送給你。
我們看到js中調用的方法是 RequestPush.onPageLoad()發現有點眼熟,其實就是我們實現的Java類.方法 好像前端可以直接像後端一樣直接調用Java的方法,我們都知道這是不可能的,那是怎麼實現的呢?
查看之前說過的前端頁面引用的的不存在的js文件中的內容發現 ,通過這個文件做橋樑來實現前後端的動態的數據交互。