提问者:小点点

如何在SpringMVC前端监控服务器端事件?


这是我的要求

  1. 在我的应用程序中,Spring-mvc在内部命中rest api并从依赖的系统中获取数据(耗时的操作)。我想从JSP页面监控这个服务器端事件
  2. 我希望有定时器/进度条用于由Spring触发的rest-api搜索。

共1个答案

匿名用户

在这种情况下,您可以使用WebSocket和STOMP协议来满足您的要求。

WebSocket

WebSocket是用户浏览器和服务器之间的双向连接。有关WebSocket的更多信息。

STOMP协议

STOMP是一个简单的(或流式)面向文本的消息传递协议,用于使用面向消息的中间件。有关STOMP的更多信息

WebSocket和STOMP协议的区别,请参考Nitin Kamate的回答。

在这个答案中,使用SockJS和Stop mjs在Spring应用程序中创建了WebSocket和通信协议。

SockJS

SockJS是一个用于创建WebSocket的java脚本库。有关SockJS的更多信息,您可以从这里下载sockjs. min.js文件。

斯坦普斯

Stompjs是一个java的脚本库,为Web浏览器提供了一个基于WebSocket的STOMP客户端。

您应该下载sockjs. min.js和gorp.min.js文件,并将这些java脚本文件添加到您的项目中,并且需要添加WebSocket库依赖项。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>x.x.x</version>
</dependency>

首先在servlet. xml中配置WebSocket

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/websocket
    https://www.springframework.org/schema/websocket/spring-websocket.xsd">

    <websocket:message-broker application-destination-prefix="/app">
        <websocket:stomp-endpoint path="/portfolio"/>
            <websocket:sockjs/>
        </websocket:stomp-endpoint>
        <websocket:stomp-broker-relay prefix="/topic"/>
    </websocket:message-broker>

</beans>
  • 应用程序-目标-前缀用作按摩映射的前缀
  • path-使用http://localhost:8080/portfoliourl连接到WebSocket
  • prefix用作STOMP目标的前缀

然后构建WebSocket客户端,如下所示,

在此示例中,我们将一些值从服务器端控制器发送到目的地

AppController.java

@Controller
public class AppController {

    @Autowired
    private SimpMessagingTemplate template; //provide methods for sending messages to a user

    @RequestMapping(value = "/event")
    public void getValue() throws InterruptedException{
        for (int i = 0; i < 100; i++) { //in this example, used for loop to generate a value in iteration
            this.template.convertAndSend("/topic/number", i); //send the value of i to destination through WebSocket
            Thread.sleep(1000); //added a delay to every round in for loop
        }
    }
}

JavaScript(SockJS)客户端,用于接收服务器端(java)事件发送的值。(另外使用了角度库来处理前端。角js教程)

app. js

var mainApp = angular.module("mainApp", []);
     
mainApp.controller('appController', function($scope, $http) {

    $scope.progress = 0; // variable declared by angular for store the value return by java
    var socket = new SockJS('/Your_Application_Name/portfolio'); //create a new SockJS WebSocket
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        stompClient.subscribe('/topic/number', function (value) {
        $scope.progress=value.body; //assigned value to progress variable
        $scope.$apply();
    });

    $scope.startEvent = function() { // this function call the getValue() function in controller
        $http.post('event').then(function(value) {

        }, function(reason) {
        
        }, function(value) {
        
        })
    }
}
});

下面的jsp文件包含按钮和进度条。使用按钮启动服务器端事件(在这个例子中,按钮名为getValue()函数在AppController.java通过角js。另外使用bootstrap框架来创建前端。引导教程)

index. jsp

<html>
   <head>
      <link rel="stylesheet" href="resources/css/bootstrap.min.css">
      <script type="text/javascript" src="resources/js/jquery.min.js"></script>
      <script type="text/javascript" src="resources/js/sockjs.min.js"></script>
      <script type="text/javascript" src="resources/js/stomp.min.js"></script>
      <script type="text/javascript" src="resources/js/bootstrap.min.js"></script>
      <script type="text/javascript" src="resources/js/angular.min.js"></script>
      <script type="text/javascript" src="resources/js/app.js"></script>
   </head>
   
   <body ng-app="mainApp" ng-controller="appController">
      <div class="container">
         <div class="progress  mb-3">
            <div class="progress-bar" role="progressbar" ng-style="{width: progress + '%'}" aria-valuenow="{{progress}}" aria-valuemin="0" aria-valuemax="100">{{progress}}%</div>
            <!--progress variable used for set value to progress bar-->
         </div>
         <button type="button" class="btn btn-outline-secondary btn-sm" ng-click="startEvent()">Start Event</button>
         <!--click event of above button call to startEvent() function in app.js file-->
      </div>
   </body>
</html>

有关WebSocket的更多详细信息,请参阅Spring留档,Spring WebSocket从这里。