DWR后台推送技术

最近工作需要写一个后台推送消息到浏览器提示用户操作的功能,在网上摸索了几天,有的是比较乱的,会造成一些误导,现在把自己应用笔记写下来跟大家分享。

第一步:下载dwr.jar、commons-logging.jar(我这里用的是dwr3.0)导入到自己的工程里。

第二步:修改web.xml,加入以下code
<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>true</param-value>

        </init-param>

        <init-param>

            <param-name>logLevel</param-name>

            <param-value>WARN</param-value>

        </init-param>
  </servlet>
  <servlet-mapping>
  
    <servlet-name>dwr-invoker</servlet-name>
    
    <url-pattern>/dwr/*</url-pattern>
  
  </servlet-mapping>

第三步:编写java类

1.MessagePush类
package com.dwr.messagemind.service;

import javax.servlet.ServletException;

import org.directwebremoting.ScriptSession;
import org.directwebremoting.WebContextFactory;

import com.dwr.messagemind.servlet.DwrScriptSessionManagerUtil;


public class MessagePush {

	 public void onPageLoad(String userId) {

         ScriptSession scriptSession = WebContextFactory.get().getScriptSession();

         System.out.println("scriptSession:" + scriptSession);
         
         scriptSession.setAttribute("userId", userId);

         DwrScriptSessionManagerUtil dwrScriptSessionManagerUtil = new DwrScriptSessionManagerUtil();

         try {

        	 dwrScriptSessionManagerUtil.init();

         } catch (ServletException e) {

                e.printStackTrace();

         }

  }
}



2.DwrScriptSessionManagerUtil类
package com.dwr.messagemind.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;

import org.directwebremoting.Container;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.event.ScriptSessionEvent;
import org.directwebremoting.event.ScriptSessionListener;
import org.directwebremoting.extend.ScriptSessionManager;
import org.directwebremoting.servlet.DwrServlet;

public class DwrScriptSessionManagerUtil extends DwrServlet {

	private static final long serialVersionUID = -7504612622407420071L;

	public void init() throws ServletException {

		Container container = ServerContextFactory.get().getContainer();

		ScriptSessionManager manager = container.getBean(ScriptSessionManager.class);

		ScriptSessionListener listener = new ScriptSessionListener() {

			public void sessionCreated(ScriptSessionEvent ev) {

				HttpSession session = WebContextFactory.get().getSession();

				//String userId = ((User) session.getAttribute("userinfo")).getHumanid() + "";
				String userId = "123";

				System.out.println("a ScriptSession is created!");

				ev.getSession().setAttribute("userId", userId);

			}

			public void sessionDestroyed(ScriptSessionEvent ev) {

				System.out.println("a ScriptSession is distroyed");

			}

		};

		manager.addScriptSessionListener(listener);

	}

}



3.DwrTool类(前台页面在需要推送的地方调用此类的方法)
package com.dwr.messagemind.service;

import java.util.Collection;

import org.directwebremoting.Browser;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ScriptSessionFilter;

public class DwrTool {

	public void sendMessageAuto(String userid, String message) {

		final String userId = userid;

		final String autoMessage = message;

		Browser.withAllSessionsFiltered(new ScriptSessionFilter() {

			public boolean match(ScriptSession session) {

				if (session.getAttribute("userId") == null) {
					return false;
				} else {
					return (session.getAttribute("userId")).equals(userId);
				}
			}

		}, new Runnable() {

			private ScriptBuffer script = new ScriptBuffer();

			public void run() {

				script.appendCall("showMessage", autoMessage);

				Collection<ScriptSession> sessions = Browser.getTargetSessions();

				for (ScriptSession scriptSession : sessions) {

					scriptSession.addScript(script);

				}

			}

		});

	}
}



第四步:配置dwr.xml,在web.xml同级位置新建dwr.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http://getahead.org/dwr/dwr30.dtd">
<dwr>
	<allow>
		<create creator="new" javascript="MessagePush">
	  		<param name="class" value="com.dwr.messagemind.service.MessagePush"/>
		</create>
		<create creator="new" javascript="DwrTool">
	  		<param name="class" value="com.dwr.messagemind.service.DwrTool"/>
		</create>
	</allow>
</dwr>


第五步:编写jsp页面测试

接收页面需要做以下变动:
<script type="text/javascript" src="<%=path%>/dwr/engine.js"></script>
        <script type="text/javascript" src="<%=path%>/dwr/util.js"></script>
        <script type="text/javascript" src="<%=path%>/dwr/interface/MessagePush.js"></script>
<script type="text/javascript">
			function onPageLoad(){
             	MessagePush.onPageLoad("123");
          	}
          	function showMessage(autoMessage) {
          		alert(autoMessage);
          		document.all.bb.innerHTML = autoMessage;
          	}
		</script>


<body onload="dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);onPageLoad();">


前两项为dwr配置,第三个调用js方法出发MessagePush.onPageLoad('')方法,注意MessagePush为在dwr中配置的类名,并且需要在页面引入MessagePush.js,这个为系统自动生成,不需要自己创建.engine.js、util.js也为系统自动生成,不需要自己创建,只许引入即可。

发送页面做以下配置

引入
		<script type="text/javascript" src="<%=request.getContextPath()%>/dwr/engine.js"></script>
        <script type="text/javascript" src="<%=request.getContextPath()%>/dwr/util.js"></script>
        <script type="text/javascript" src="<%=request.getContextPath()%>/dwr/interface/DwrTool.js"></script>

<script type="text/javascript">
		
		function send(message) {
			DwrTool.sendMessageAuto("123", message);
		}
</script>

在需要调用的地方调用js方法send('')即可。

注:因为dwr用的ajax反转方式实现推送,所以如果在ajax方法里调用send()是没有效果的,会报异常,当然在发送页面将dwr设置成同步方式可以发送成功(我实验的时候会先弹出一个错误窗口,但是还可以实现效果),只许在<body>加入
onlocad="dwr.engine.setAsync(false);"


当然如果出现弹出错误窗口交互不好,继续想办法,既然不能在ajax里面调用,还希望成功的时候调用send(),那就用<iframe>吧,

<form action="你要请求的servlet" method="post" id="inputform" name="inputform" target="hidden_frame">
			<iframe id="hidden_frame" name="hidden_frame" style="display: none;"></iframe>


接下来提交form到后台servlet,后台处理成功之后调用send();
response.getWriter().print("<script>");
				response.getWriter().print("parent.send('成功了');");
				response.getWriter().print("</script>");


至此已经都说完了,如果有疑问请留言吧。

你可能感兴趣的:(java,DWR,推送)