springMVC整合DWR3.0 与实例

SpringMVC整合DWR3.0 与实例

从网上找了好多资料,都不完整,花了好长时间才弄好,现在整理一下,给朋友们分享一下,也希望能提出问题,完善项目。

1、  首先要下载DWR3.0JAR包(这个是必须的,不多解释哈)

DWR3.0下载地址http://download.csdn.net/detail/qfq1990/7866807

 

2、  配置项目web.xml文件

<servlet>

           <servlet-name>springMVC</servlet-name>

           <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

           <load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

           <servlet-name>springMVC</servlet-name>

           <url-pattern>/</url-pattern>

</servlet-mapping>

<servlet-mapping>

     <servlet-name>springMVC</servlet-name>

     <url-pattern>/dwr/*</url-pattern>

</servlet-mapping>

3、  配置springMVC-servlet.xml文件

<beansxmlns="http://www.springframework.org/schema/beans"

xmlns:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p"

xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"

xsi:schemaLocation="http://www.springframework.org/schema/beans

     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

     http://www.springframework.org/schema/context

      http://www.springframework.org/schema/context/spring-context.xsd

      http://www.directwebremoting.org/schema/spring-dwr  

     http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd  

      http://www.springframework.org/schema/mvc

     http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

 

 

 

 

 

 

 

 

<beanclass="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">

           <propertyname="mediaTypes">

                    <map>

                             <entrykey="json" value="application/json"></entry>

                             <entrykey="xml" value="text/xml"></entry>

                             <entrykey="htm" value="text/html"></entry>

                    </map>

           </property>

</bean>

<context:component-scanbase-package="com.pfxt.controller" />

<mvc:annotation-driven />

 

<mvc:resourcesmapping="/resources/**" location="/WEB-INF/resources/"/>

 

<!-- 对模型视图名称的解析,在请求时模型视图名称添加前后缀 -->

<bean

           class="org.springframework.web.servlet.view.InternalResourceViewResolver">

           <propertyname="viewClass"

                    value="org.springframework.web.servlet.view.JstlView"/>

           <property name="prefix"value="/WEB-INF/jsp/" />

           <property name="suffix"value=".jsp" />

</bean>

<!-- DWR配置 --> 

<bean id="simpleUrlHandlerMapping"class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> 

<!-- 要求dwr在spring容器中检查拥有@RemoteProxy和 @RemoteMethod注解的类。注意它不会去检查Spring容器之外的类。 --> 

<dwr:annotation-config id="dwr"/> 

<!-- 要求DWR将util.js和engine.js映射到dwrController--> 

<dwr:url-mapping /> 

<!-- 定义dwr --> 

<dwr:controller id="dwrController"debug="true"> 

   <dwr:config-param name="allowScriptTagRemoting" 

             value="true" /> 

   <dwr:config-param name="crossDomainSessionSecurity"

             value="false" />

   <dwr:config-param name="classes" 

             value="java.lang.Object"/>

   <dwr:config-param name="activeReverseAjaxEnabled"  

             value="true" />

   <!-- script session 的超时设置  默认值:1800000(30分钟) -->

   <dwr:config-param name="scriptSessionTimeout" 

             value="3600000" />

   <dwr:config-param name="initApplicationScopeCreatorsAtStartup" 

             value="true" />

   <dwr:config-paramname="org.directwebremoting.extend.ScriptSessionManager" 

       value="com.pfxt.util.DWRScriptSessionManager"/>  

</dwr:controller> 

<!-- DWR配置 -->

 

注:这样在服务器启动时即会绑定 ScriptSessionListener ScriptSession在创建时会自动添加到我们维护的Map中(后面会有解释)

 

 

以下是对SercriptSession的优化及维护

服务器的推送功能,但是根据 ScriptSession的生命周期我们可以得出以下几点的问题:

 

1ScriptSession不会与HttpSession同时创建

当我们访问一个页面的时候,如果是第一次访问,就会创建一个新的HttpSession,之后再访问的时候,就会保持当前的Session,即使是刷新,也能保持当前的HttpSession

但是,ScriptSession不同,第一次访问,会创建一个ScriptSession,但是,如果你刷新,就会创建一个新的ScriptSession.

 

2)如何得到ScriptSession

DWR中,我们可以通过WebContextFactory.get()来取得一个WebContext对象,进而通过WebContextgetScriptSession()取得ScriptSession对象。

但是要注意,在我们自定义的Servlet中,我们也可以通过WebContextFactory.get()来取得一个WebContext,但是这种方法却不能取得ScriptSession对象。因为,此WebContext对象其实不是通过DWR的上下文环境得到的,所以,就根本没有创建ScriptSession对象。

假设这种方式也能得到ScriptSession的话,那么我们实现也就可以不局限在DWR的上下文环境中了,那么其灵活性就会大很多了。所以,这就是我们不能在Servlet中实现推的原因。

 

3关于刷新就创建一个新的ScriptSession问题

 在我们需要推送的页面中,如果你刷新一下,那么就提交一个Httprequest,此时,如果是第一次,那么就会创建一个httpSession对象,同时,请求由DwrServlet来处理后,就会创建一个ScriptSession.这个ScriptSession会和你的request请求的URI绑定放在一个由ScriptSessionManager维护的Map里面(这里面其实是一个URI对应的Set,Set里面放置的是URI绑定的所有ScriptSession)。

当你刷新的时候,同样的一个HttpSession,却会创建一个新的ScriptSession,然后绑定到对应的URI上。

 

 4)向所有的页面访问者推送
当我们想向所有的页面访问者推送的时候,我们只需要,取得所有的页面访问者,就可以了。
如何取得所有的页面访问者?

 

DWR3.0可以通过

1. //得到所有ScriptSession  

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


DWR2.x
可以通过

1. Collection pages = webContext.getScriptSessionsByPage("/yourPage.jsp");  

 

通过此方法,就可以实现调用客户端的javascript函数,实现对客户端的操作。

5在上面的推送中产生的问题
上面的方法已经可以实现向所有的访问者推送。但是问题是,在客户端,如果用户刷新一次或多次,那么,Collection里面可能就保存了很多的无用的ScriptSession,所以不仅仅会影响性能问题,更重要的是,可能就不能实现你想要的功能。

 

2.如何管理有效的ScriptSession

 

     由于上面的问题,我们就需要自己管理ScriptSession。其实,有效地HttpSession,就是那个和当前的HttpSession匹配的ScriptSession

所以,我们就可以自己维护一个Map,在这个Map里面,我们定义key就是HttpSessionId,其值就是ScriptSession对象。

在每一次页面载入的时候,都去注册此ScriptSession,那么就会把新的ScriptSession绑定到httpSession上面了。

 

DWR3.0中推出了ScriptSessionListener用来监听ScriptSession的创建及销毁事件。我们可以使用该监听器来维护我们自己的Map

 

1.新建一个类实现 ScriptSessionListener接口

1. package sugar.dwr;  

2.   

3. import java.util.Collection;  

4. import java.util.HashMap;  

5. import java.util.Map;  

6.   

7. import javax.servlet.http.HttpSession;  

8.   

9. import org.directwebremoting.ScriptSession;  

10. import org.directwebremoting.WebContext;  

11. import org.directwebremoting.WebContextFactory;  

12. import org.directwebremoting.event.ScriptSessionEvent;  

13. import org.directwebremoting.event.ScriptSessionListener;  

14.   

15. public class DWRScriptSessionListener implements ScriptSessionListener {  

16.        

17.      //维护一个Map keysessionId valueScriptSession对象  

18.      public static final Map<String, ScriptSession> scriptSessionMap = new HashMap<String, ScriptSession>();  

19.   

20.      /** 

21.       * ScriptSession创建事件 

22.       */  

23.      public void sessionCreated(ScriptSessionEvent event) {  

24.            WebContext webContext = WebContextFactory. get();  

25.            HttpSession session = webContext.getSession();  

26.            ScriptSession scriptSession = event.getSession();  

27.             scriptSessionMap.put(session.getId(), scriptSession);     //添加scriptSession  

28.            System. out.println( "session: " + session.getId() + " scriptSession: " + scriptSession.getId() + "is created!");  

29.      }  

30.   

31.      /** 

32.       * ScriptSession销毁事件 

33.       */  

34.      public void sessionDestroyed(ScriptSessionEvent event) {  

35.            WebContext webContext = WebContextFactory. get();  

36.            HttpSession session = webContext.getSession();  

37.            ScriptSession scriptSession = scriptSessionMap.remove(session.getId());  //移除scriptSession  

38.            System. out.println( "session: " + session.getId() + " scriptSession: " + scriptSession.getId() + "is destroyed!");  

39.      }  

40.        

41.      /** 

42.       * 获取所有ScriptSession 

43.       */  

44.      public static Collection<ScriptSession> getScriptSessions(){  

45.             return scriptSessionMap.values();  

46.      }  

47. }  


2.
新建一个类继承 DefaultScriptSessionManager,用来绑定 DWRScriptSessionListener

1. package sugar.dwr;  

2.   

3. import org.directwebremoting.impl.DefaultScriptSessionManager;  

4.   

5. public class DWRScriptSessionManager extends DefaultScriptSessionManager {  

6.      public DWRScriptSessionManager(){  

7.             //绑定一个ScriptSession增加销毁事件的监听器  

8.             this.addScriptSessionListener( new DWRScriptSessionListener());  

9.            System. out.println( "bind DWRScriptSessionListener");  

10.      }  

11. }  


3.
 DWRScriptSessionManager  配置在 springMVC-servlet.xml中上面已经提到过

        

这样在服务器启动时即会绑定 ScriptSessionListener ScriptSession在创建时会自动添加到我们维护的Map

 

4.通过以下方法获取所有的 ScriptSession

1. //得到所有ScriptSession  

2. Collection<ScriptSession> sessions = DWRScriptSessionListener.getScriptSessions();  

 

3.使用 ScriptSessionFilter过滤

     如果我们不想要给所有的客户端 推送消息,只想给特定的客户端推送,那么我们可以使用 ScriptSessionFilter来实现。在filter中去判定session中的Attribute值是不是我们给定的。

 

1.使用以下方法推送消息

//执行推送
Browser.withAllSessionsFiltered(filter, run); //注意这里调用了有filter功能的方法

2.推送这个地方自己写了一个Util 工具类 SendMessageAutoUtil

import java.util.Collection;

import java.util.List;

 

import org.directwebremoting.Browser;

import org.directwebremoting.ScriptBuffer;

import org.directwebremoting.ScriptSession;

import org.directwebremoting.ScriptSessionFilter;

 

import com.pfxt.pojo.Pf_stuxx;

 

public class SendMessageAutoUtil {

    //消息推送  指定某个客户端的页面显示

    public static voidsendMessageAuto(String userid,String message,String showScriptMethod) {

            final String yhId = userid ;//页面标志

            final String autoMessage = message;//返回的数据

            final String autoShowScriptMethod =showScriptMethod;//返回页面要调用的JS方法

             //执行推送 

            Browser.withAllSessionsFiltered(newScriptSessionFilter(){ 

                public boolean match(ScriptSessionscriptSession) { 

                    String yhid =(String)scriptSession.getAttribute("yhId");

                    if(yhid!=null){

                        return yhId.equals(yhid);

                    }else{

                        return false;

                    }

                } 

              }, new Runnable(){ 

                  private ScriptBuffer script = newScriptBuffer(); 

                  public void run() { 

                       //设置要调用的 js及参数 

                      script.appendCall(autoShowScriptMethod, autoMessage); 

                       //得到过滤之后的ScriptSession 

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

                       //遍历每一个ScriptSession 

                       for (ScriptSession scriptSession: sessions){ 

                            scriptSession.addScript(script); 

                      } 

                 } 

            });//注意这里调用了有filter功能的方法 

        }

//消息推送  指定某个客户端的页面显示 此方法是把要推送的ID放到集合

public static  voidsendMessageListAuto(List targetYhidList,Pf_stuxx stuxx,String showScriptMethod){

            final List targetIdList =targetYhidList ;

            final Pf_stuxx autoMessage = stuxx;

            final String autoShowScriptMethod =showScriptMethod;

           

            //执行推送 

            Browser. withAllSessionsFiltered(newScriptSessionFilter() { 

                public boolean match(ScriptSessionscriptSession) { 

                    String yhid =(String)scriptSession.getAttribute("yhId"); 

                    if(yhid!=null &&targetIdList.contains(yhid)){

                        //return yhid.equals(yhId);

                        targetIdList.remove(yhid);//如果找到了,说明将被推送,所以不用再处理,剩下的都是要被处理的

                        return true;

                    }else{

                        return false;

                    }

               } 

          }, new Runnable(){ 

              private ScriptBuffer script = newScriptBuffer(); 

              public void run() { 

                   //设置要调用的 js及参数 

                   script.appendCall(autoShowScriptMethod,autoMessage); 

                   //得到过滤之后的ScriptSession 

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

                   //遍历每一个ScriptSession 

                   for (ScriptSession scriptSession: sessions){ 

                       scriptSession.addScript(script); 

                  } 

             } 

        });//注意这里调用了有filter功能的方法 

    }

}


3.
在打开jsp页面时需要在 ScriptSession 中注入设定的attributeMessagePush中的方法

       新建一个Controller

    import java.util.List;

 

import javax.annotation.Resource;

importjavax.servlet.ServletException;

importjavax.servlet.http.HttpSession;

 

importorg.directwebremoting.ScriptSession;

importorg.directwebremoting.WebContextFactory;

importorg.directwebremoting.annotations.RemoteMethod;

importorg.directwebremoting.annotations.RemoteProxy;

importorg.springframework.stereotype.Controller;

importorg.springframework.ui.Model;

importorg.springframework.web.bind.annotation.RequestMapping;

importorg.springframework.web.bind.annotation.ResponseBody;

 

 

 

 

 

import com.pfxt.pojo.Pf_xmjc;

import com.pfxt.pojo.Pf_yhxx;

importcom.pfxt.service.YhxxService;

importcom.pfxt.util.DwrScriptSessionManagerUtil;

 

@Controller

@RemoteProxy(name="directController")

public class DirectController {

    @Resource(name = "yhxxService") 

    private YhxxService yhxxService;

   

 

    @RemoteMethod

    public void onPageLoad(final String yhId) {

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

       scriptSession.setAttribute("yhId", yhId);

        System. out.println("创建连接+"+yhId);

    }

}


4.
jsp中调用该方法

<script type="text/javascript"src="<%=path%>/resources/js/jquery-1.9.1.min.js"></script>

<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/directController.js"></script>

<script type= "text/javascript">
        $(document).ready(function(){
                  //这个方法用来启动该页面的ReverseAjax功能
                  dwr.engine.setActiveReverseAjax(true);
                  //设置在页面关闭时,通知服务端销毁会话
                  dwr.engine.setNotifyServerOnPageUnload(true);
                  //设置DWR调用服务出错时,不打印(alert)调试信息 
                 dwr.engine.setErrorHandler(function() { 
                     // 
                 });
                  onPageLoad();
             })
             function onPageLoad(){
                  directController.onPageLoad("568839130");
             }
             function showMessage(autoMessage){
                  //
             }
</script >

这样我们可以给不同客户端的jsp中导入不同的tag值,过滤推送的客户端.

 

到此为止spingMVC整合DWR3.0结束,有些地方是转载其他大神的,在大神的基础上做了一些修改和总结,现在分享给大家,共同学习成长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值