DWR简介:
逆向AJAX技术:
DWR是一个Java库,使服务器上的Java和JavaScript的浏览器进行交互和相互调用尽可能简单。
DWR 是一个可以允许你去创建 AJAX WEB 站点的 JAVA 开源库。它可以让你在浏览器中的 Javascript 代码调用 Web 服务器上的 Java 代码,就像在 Java 代码就在浏览器中一样。
DWR推送技术有三种模式:
piggyback(捎带模式):默认模式:
如果后台有什么内容需要推送到前台,是要等到那个页面进行下一次ajax请求的时候,将需要推送的内容附加在该次请求之后,传回到页面。
comet(长连接模式):
当服务端建立和浏览器的连接,将页面内容发送到浏览器之后,对应的连接并不关闭,只是暂时挂起。如果后面有什么新的内容需要推送到客户端的时候直接通过前面挂起的连接再次传送数据。
服务器所能提供的连接数目是一定的,在大量的挂起的连接没有关闭的情况下,可能造成新的连接请求不能接入,从而影响到服务质量。
polling(轮询模式):AJAX轮询,效率最低,可以直接用jquery代替
当系统的主要功能需要用推送来完成且实时性要求高连接数不大的情况下可以使用Comet,连接数较大且对实时性没有较高要求(一分钟或以上)可以使用Polling,不建议使用Piggyback
推送模式配置方式:web-xml中配置
<!-- polling模式 -->
<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>
pom文件:(通过maven自动下载的jar包有问题,会报找不到配置文件的错,建议直接去官方网站下jar包,手动导入仓库)
<!--DWR-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.directwebremoting</groupId>
<artifactId>dwr</artifactId>
<version>3.0.M1</version>
</dependency>
web-xml中配置:
<!--DWR-->
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<!-- 接收js的Ajax请求的servlet -->
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<!-- 支持逆向Ajax -->
<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>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<!-- 拦截指定的URL -->
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
新建DWR配置文件:配置前端访问的类
<dwr>
<allow>
<create creator="new" javascript="Demo">
//前端访问的实体类
<param name="class" value="com.dwr.Demo" />
</create>
//向前台返回实体类时需进行配置,将实体类转成JSON格式返回
<convert converter="bean" match="com.nova.his.core.persistence.page.PageList"></convert>
</allow>
</dwr>
前端页面:
发送消息页面:
<%--引入DWR--%>
<script type='text/javascript' src='${ctx}/dwr/engine.js'></script>
<script type='text/javascript' src='${ctx}/dwr/util.js'></script>
<%--dwr通过dwr.xml生成该js--%>
<script type='text/javascript' src='${ctx}/dwr/interface/Demo.js'></script>
//直接通过类名.方法名调用,
Demo.add(JSON.stringify(render),function (data) {
});
接受消息页面:
<script type='text/javascript' src='${ctx}/dwr/engine.js'></script>
<script type='text/javascript' src='${ctx}/dwr/util.js'></script>
<script type='text/javascript' src='${ctx}/dwr/interface/Demo.js'></script>
window.onload = function(){
//开启逆向Ajax功能
dwr.engine.setActiveReverseAjax(true);
//开启关闭页面提醒服务器功能
dwr.engine.setNotifyServerOnPageUnload(true);
//对当前用户进行注册,提供token
Demo.regist();
}
//接受后台返回值方法
function receiveMessages(messages) {
}
后台方法:
//注册信息,双方通信需通过一个token来实现精准推送,下面可以将userId放在DWR的ScriptSession 中,
public void regist(){
//获取当前scriptSession
ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
HttpSession session = WebContextFactory.get().getSession();
UserSession userSession = (UserSession) session.getAttribute(WebUtil.DEFAULT_USER_SESSION_KEY);
scriptSession.setAttribute("key",userSession.getYgdm());
}
@RemoteMethod
public int add(String json){
HttpSession session = WebContextFactory.get().getSession();
final UserSession userSession = (UserSession)session.getAttribute(WebUtil.DEFAULT_USER_SESSION_KEY);
HttpSession session = WebContextFactory.get().getSession();
final UserSession userSession = (UserSession) session.getAttribute(WebUtil.DEFAULT_USER_SESSION_KEY);
Browser.withAllSessionsFiltered(new ScriptSessionFilter() {
@Override
//匹配token
public boolean match(ScriptSession scriptSession) {
if (null == scriptSession.getAttribute("key")){
return false;
}else {
return scriptSession.getAttribute("key").equals(userSession.getYgdm());
}
}
}, new Runnable() {
//开启推送线程
private ScriptBuffer scriptBuffer = new ScriptBuffer();
@Override
public void run() {
Collection<ScriptSession> sessions = Browser.getTargetSessions();
//receiveMessages为前端渲染数据的方法
scriptBuffer.appendCall("receiveMessages",true);
for (ScriptSession scriptSession : sessions) {
if(scriptSession.getAttribute("key").equals(userSession.getYgdm())){
scriptSession.addScript(scriptBuffer);
break;
}
}
}
});
}
注:此种方法会导致页面刷先scriptSession找不到了,后续附上优化;