软件151 苏垚
本篇博客我们继续的来聊SpringMVC的东西,下方我们将会聊到js、css这些静态文件的加载配置,以及服务器推送的两种实现方式。当然我们在服务器推送时,会用到JQuery的东西,所以我们先聊一下如何加载静态资源文件,然后我们再聊如何实现服务器推送。
下方给出了两种实现服务器推送的方式,一种是SSE(Server Send Event (服务端推送事件))另一种是基于Servlet异步处理的推送,下方会给出详细的实现方式,并且给出了两者的区别。
一、静态资源文件映射
静态资源文件映射在SpringMVC中的配置也是比较简单的、在我们Spring的Config文件里边配置一下即可。下方就是我们在配置静态资源文件时所做的内容。
1、映射资源文件
首先我们在src/main/resources包下方创建了衣蛾assets文件,该文件下就存放着我们工程中所使用所有的静态资源文件。然后我们在Spring的配置文件中重写addResourceHandlers()方法,使用该方法来配置“assets”目录。
2、资源文件的引用
我们来创建一个jquery_test.jsp文件,该文件中引入了assets文件夹中js文件夹下的jquery.js文件。在jquery_test.jsp中就使用了jQuery的东西。下方就是该文件的所有内容。当然下方页面的功能比较简单,就是点击按钮,往HTML中动态的添加新的节点。具体代码如下所示:
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>
3、测试上述页面
当然要想访问上述页面,还得在Spring的配置文件中进行路由的配置。下方代码段就是Spring配置文件中静态文件路由的快速配置。
下方就是我们对相应路由的访问结果,如下所示。通过下方示例,我们可以看到jquery.js资源文件可以被正常的访问到。
二、Server Send Event (服务端推送事件)
Server Send Event简称SSE,使用该技术可以实现服务端像浏览器发送事件,也就是所谓的服务端的PUSH。本篇博客所聊的服务器推送技术的实现原理是当客户端向服务端发送请求时,服务端会抓住这个请求不放,等有数据更新的时候才返回给客户端。当客户端接收到消息后,再向服务端发送请求,周而复始。
服务端推送以及客户端发送的网络请求都是单向通信,后面的博客我们会介绍一种双向通信技术:WebSocket。本篇我们就先聊聊服务端的推送事件。
1.创建SSEController
首先我们创建一个普通的SpringMVC的Controller,命名为SSEContrller。下方就是SSEController类的具体实现,内容与普通的Controller差不多。只不过相应的方法在路由配置时,将produces属性的文本类型设置成“text/event-stream”即可。
在下方类的push()方法中,每500ms就会往客户端发送一个消息。消息的内容是当前时间,如下所示:
2、创建请求的JSP页面
创建好上述类后,我们就该创建测试上述Controller的JSP页面了,我们在相应的资源目录中创建一个sse.jsp页面。在sse.jsp页面中,我们将会使用到JavaScript中的EventSource对象来监听来着“/sse”路由的事件消息,当收到上述Controller发起的事件后,会在事件回调中做一些事情。当然,我们做的事情就是在HTML页面中添加新的节点,将事件响应的消息添加到HTML文本只能怪进行显示。
下方就是sse.jsp页面的具体代码。
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("连接关闭"); 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>
3、测试我们的SSE
上面的事件发送端以及事件监听端的代码已实现完毕。接下来我们就要进行测试了。在测试之前,我们还要做一件事情,就是为我们的sse.jsp页面添加访问路由。我们就选择在Spring的配置文件中进行快速配置sse.jsp页面的路由。下方就是sse.jsp路由配置的相关代码:
registry.addViewController("/ssetest").setViewName("/sse");
配置完上述路由后我们就可以访问上述路由所对应的JSP页面了,下方就是具体的运行效果。从下方演示效果中,我们不难看出,每隔一段时间就会收到来自服务端的消息事件,具体如下所示:
三、Servlet中的异步推送
接下来我们来使用Servlet的异步处理以及Spring的任务计划(定时器)来实现事件的推送。当然本部分的最终实现效果与上述效果是一样的,只不过是实现方式不同。SSE是需要新式浏览器的支持,而Servlet的异步方法进行推送是跨浏览器的。接下来我们就来好好的来实现该技术点。
1、 实现Servlet中的异步推送前的配置
首先我们需要在Spring的配置文件中进行配置,是我们的Spring支持计划任务(Scheduleing),其实就是支持定时器。因为我们要定时的向客户端进行push,所以定时器的配置是必须的。
启动完定时器后,我们需要在Web初始化的类中开启Servlet的异步支持,如下所示。
2、创建Push Service
相关配置完成后,接下来我们要做的就是创建我们的Push Service。该Service就负责往客户端进行Push事件,Push Service的类对象就是我们相应Controller的依赖对象 ,稍后,我们将会将该依赖注入到相应的Controller中进行事件的Push。
下方就是PushService类的具体代码实现,需要使用@Service进行修饰。然后实例化一个DeferredResult对象负责传递事件消息。我们用到了@Scheduled注解来设定每次推送的间隔。
上面用到了@Service注解,我们可以点进去看一下Service注解中的内容。从其源码中我们不难看出其实@Service和@Component用法是一至的。@Service注解的实现如下所示:
3、创建调用PushService的Controller
创建完PushService后,接着就创建一个调用PushService的Controller类。下方这个ServletAsyncController就是负责调用PushService对象的Controller。其中使用了@Autowired注解来声明依赖注入的注入点。然后通过路由,路由到调用PushService的方法中即可。DeferredResult<String>就是推送事件的载体、而消息的类型是String类型。具体实现如下所示:
4、接收事件的JSP页面的实现
创建完Push Service以及负责推送的Controller后,接下来我们就该创建接收推送的客户端代码了。下方的代码比较简单,主要是使用jQuery来接收的推送事件。然后将推送的内容append到html中进行显示,如下所示:
<%@ 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>
给上述JSP页面配置路由的代码在此就省略了,和之前一样,给上述JSP页面在SpringConfig文件中配置一个路由,此处是“/async_push”, 然后我们对该路由进行访问,下方就是访问效果,如下所:
本篇博客就先到此,上述示例在github上的分享地址为:https://github.com/lizelu/SpringMVCWithMaven
来源:https://www.cnblogs.com/sy399/p/7093284.html