在上篇博客中,我們聊了《JavaEE開發(fā)之SpringMVC中的自定義攔截器及異常處理》。本篇博客我們繼續(xù)的來聊SpringMVC的東西,下方我們將會聊到js、css這些靜態(tài)文件的加載配置,以及服務(wù)器推送的兩種實現(xiàn)方式。當(dāng)然我們在服務(wù)器推送時,會用到JQuery的東西,所以我們先聊一下如何加載靜態(tài)資源文件,然后我們再聊如何實現(xiàn)服務(wù)器推送。

下方給出了兩種實現(xiàn)服務(wù)器推送的方式,一種是SSE(Server Send Event (服務(wù)端推送事件))另一種是基于Servlet異步處理的推送,下方會給出詳細(xì)的實現(xiàn)方式,并且給出了兩者的區(qū)別。

 

一、靜態(tài)資源文件映射

靜態(tài)資源文件映射在SpringMVC中的配置也是比較簡單的、在我們Spring的Config文件里邊配置一下即可。下方就是我們在配置靜態(tài)資源文件時所做的內(nèi)容。

 

1、映射資源文件

首先我們在src/main/resources包下方創(chuàng)建了衣蛾assets文件,該文件下就存放著我們工程中所使用所有的靜態(tài)資源文件。然后我們在Spring的配置文件中重寫addResourceHandlers()方法,使用該方法來配置“assets”目錄。

  萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

 

2、資源文件的引用

我們來創(chuàng)建一個jquery_test.jsp文件,該文件中引入了assets文件夾中js文件夾下的jquery.js文件。在jquery_test.jsp中就使用了jQuery的東西。下方就是該文件的所有內(nèi)容。當(dāng)然下方頁面的功能比較簡單,就是點擊按鈕,往HTML中動態(tài)的添加新的節(jié)點。具體代碼如下所示:

萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2     pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <script type="text/javascript" src="assets/js/jquery.js"></script> 8 <script type="text/javascript"> 9     $(document).ready(function(){10       $("#click").click(function(){11           $("#test").append("<h2>Hello Spring MVC</h2>");12       });13     });14     15 </script>16 <title>JQuery Demo</title>17 </head>18 <body>19 <input type="button" id="click" value="JQuery-TEST-Click me"/>20 <h2 id="test"></h2>21 </body>22 </html>

萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

3、測試上述頁面

當(dāng)然要想訪問上述頁面,還得在Spring的配置文件中進行路由的配置。下方代碼段就是Spring配置文件中靜態(tài)文件路由的快速配置。

  萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

下方就是我們對相應(yīng)路由的訪問結(jié)果,如下所示。通過下方示例,我們可以看到jquery.js資源文件可以被正常的訪問到。

  萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

 

 

二、Server Send Event (服務(wù)端推送事件)

Server Send Event簡稱SSE,使用該技術(shù)可以實現(xiàn)服務(wù)端像瀏覽器發(fā)送事件,也就是所謂的服務(wù)端的PUSH。本篇博客所聊的服務(wù)器推送技術(shù)的實現(xiàn)原理是當(dāng)客戶端向服務(wù)端發(fā)送請求時,服務(wù)端會抓住這個請求不放,等有數(shù)據(jù)更新的時候才返回給客戶端。當(dāng)客戶端接收到消息后,再向服務(wù)端發(fā)送請求,周而復(fù)始。

服務(wù)端推送以及客戶端發(fā)送的網(wǎng)絡(luò)請求都是單向通信,后面的博客我們會介紹一種雙向通信技術(shù):WebSocket。本篇我們就先聊聊服務(wù)端的推送事件。

 

1.創(chuàng)建SSEController

首先我們創(chuàng)建一個普通的SpringMVC的Controller,命名為SSEContrller。下方就是SSEController類的具體實現(xiàn),內(nèi)容與普通的Controller差不多。只不過相應(yīng)的方法在路由配置時,將produces屬性的文本類型設(shè)置成“text/event-stream”即可。

在下方類的push()方法中,每500ms就會往客戶端發(fā)送一個消息。消息的內(nèi)容是當(dāng)前時間,如下所示:

  萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

 

2、創(chuàng)建請求的JSP頁面

創(chuàng)建好上述類后,我們就該創(chuàng)建測試上述Controller的JSP頁面了,我們在相應(yīng)的資源目錄中創(chuàng)建一個sse.jsp頁面。在sse.jsp頁面中,我們將會使用到JavaScript中的EventSource對象來監(jiān)聽來著“/sse”路由的事件消息,當(dāng)收到上述Controller發(fā)起的事件后,會在事件回調(diào)中做一些事情。當(dāng)然,我們做的事情就是在HTML頁面中添加新的節(jié)點,將事件響應(yīng)的消息添加到HTML文本只能怪進行顯示。

下方就是sse.jsp頁面的具體代碼。

萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2     pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <script type="text/javascript" src="assets/js/jquery.js"></script> 8 <script type="text/javascript"> 9      if(window.EventSource){10         var source = new EventSource('sse');11         s = '';12         source.addEventListener('message', function (e) {13             s += e.data+"<br/>";14             $("#msgFromSSE").html(s);15         });16 17         source.addEventListener('open', function (e) {18             console.log("連接打開");19         }, false);20 21         source.addEventListener('error', function (e) {22             if (e.readyState == EventSource.CLOSED) {23                 console.log("連接關(guān)閉");24             } else {25                 console.log(e.readyState);26             }27         }, false);28     } else {29         console.log("瀏覽器不支持SSE");30     } 
31 </script>32 <title>SSE Demo</title>33 </head>34 <body>35 <h1>SSE-TEST</h1>36 <div id="msgFromSSE"></div>37 </body>38 </html>

萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

3、測試我們的SSE

上面的事件發(fā)送端以及事件監(jiān)聽端的代碼已實現(xiàn)完畢。接下來我們就要進行測試了。在測試之前,我們還要做一件事情,就是為我們的sse.jsp頁面添加訪問路由。我們就選擇在Spring的配置文件中進行快速配置sse.jsp頁面的路由。下方就是sse.jsp路由配置的相關(guān)代碼:

registry.addViewController("/ssetest").setViewName("/sse");

 

配置完上述路由后我們就可以訪問上述路由所對應(yīng)的JSP頁面了,下方就是具體的運行效果。從下方演示效果中,我們不難看出,每隔一段時間就會收到來自服務(wù)端的消息事件,具體如下所示:

  萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

 

 

三、Servlet中的異步推送

接下來我們來使用Servlet的異步處理以及Spring的任務(wù)計劃(定時器)來實現(xiàn)事件的推送。當(dāng)然本部分的最終實現(xiàn)效果與上述效果是一樣的,只不過是實現(xiàn)方式不同。SSE是需要新式瀏覽器的支持,而Servlet的異步方法進行推送是跨瀏覽器的。接下來我們就來好好的來實現(xiàn)該技術(shù)點。

 

1、 實現(xiàn)Servlet中的異步推送前的配置

首先我們需要在Spring的配置文件中進行配置,是我們的Spring支持計劃任務(wù)(Scheduleing),其實就是支持定時器。因為我們要定時的向客戶端進行push,所以定時器的配置是必須的。

  萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

啟動完定時器后,我們需要在Web初始化的類中開啟Servlet的異步支持,如下所示。 

  萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

 

2、創(chuàng)建Push Service

相關(guān)配置完成后,接下來我們要做的就是創(chuàng)建我們的Push Service。該Service就負(fù)責(zé)往客戶端進行Push事件,Push Service的類對象就是我們相應(yīng)Controller的依賴對象 ,稍后,我們將會將該依賴注入到相應(yīng)的Controller中進行事件的Push。

下方就是PushService類的具體代碼實現(xiàn),需要使用@Service進行修飾。然后實例化一個DeferredResult對象負(fù)責(zé)傳遞事件消息。我們用到了@Scheduled注解來設(shè)定每次推送的間隔。

  萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

上面用到了@Service注解,我們可以點進去看一下Service注解中的內(nèi)容。從其源碼中我們不難看出其實@Service和@Component用法是一至的。@Service注解的實現(xiàn)如下所示:

  萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

 

3、創(chuàng)建調(diào)用PushService的Controller

創(chuàng)建完PushService后,接著就創(chuàng)建一個調(diào)用PushService的Controller類。下方這個ServletAsyncController就是負(fù)責(zé)調(diào)用PushService對象的Controller。其中使用了@Autowired注解來聲明依賴注入的注入點。然后通過路由,路由到調(diào)用PushService的方法中即可。DeferredResult<String>就是推送事件的載體、而消息的類型是String類型。具體實現(xiàn)如下所示:

  萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

 

4、接收事件的JSP頁面的實現(xiàn)

創(chuàng)建完Push Service以及負(fù)責(zé)推送的Controller后,接下來我們就該創(chuàng)建接收推送的客戶端代碼了。下方的代碼比較簡單,主要是使用jQuery來接收的推送事件。然后將推送的內(nèi)容append到html中進行顯示,如下所示:

萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><script type="text/javascript" src="assets/js/jquery.js"></script><script type="text/javascript">

    deferred();    function deferred() {
        $.get('servlet_push', function (data) {
            $("#content").append(data+'<br/>');
            deferred();
        });
    }</script><title>Servlet_Async</title></head><body>
    <div id='content'></div></body></html>

萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

給上述JSP頁面配置路由的代碼在此就省略了,和之前一樣,給上述JSP頁面在SpringConfig文件中配置一個路由,此處是“/async_push”, 然后我們對該路由進行訪問,下方就是訪問效果,如下所:

  萬碼學(xué)堂,電腦培訓(xùn),計算機培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

 

本篇博客就先到此,上述示例在github上的分享地址為:https://github.com/lizelu/SpringMVCWithMaven

 

作者:青玉伏案 
出處:http://www.cnblogs.com/ludashi/ 
本文版權(quán)歸作者和共博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。 
如果文中有什么錯誤,歡迎指出。以免更多的人被誤導(dǎo)。

http://www.cnblogs.com/ludashi/p/6520692.html