【问题标题】:How to monitor server side event in spring MVC front end?如何在 Spring MVC 前端监控服务器端事件?
【发布时间】:2021-05-25 15:56:19
【问题描述】:

这是我的要求

  1. 在我的应用程序中,Spring-mvc 在内部访问其余 api 并从依赖系统获取数据(耗时操作)。我想从 JSP 页面监控这个服务器端事件
  2. 我想为 spring 触发的 rest-api 搜索设置计时器/进度条。

【问题讨论】:

    标签: spring spring-mvc jsp


    【解决方案1】:

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

    WebSocket

    WebSocket 是用户浏览器和服务器之间的双向连接。 for more info about WebSocket.

    STOMP 协议

    STOMP 是一种简单(或流式)的面向文本的消息传递协议,用于与面向消息的中间件一起使用。 for more info about STOMP

    WebSocket 和 STOMP 协议的区别,please refer Nitin Kamate answer

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

    SockJS

    SockJS 是一个用于创建 WebSocket 的 java 脚本库。 for more info about SockJSyou can download sockjs.min.js file from here

    stompjs

    stompjs 是一个 java 脚本库,用于为 Web 浏览器提供 STOMP over WebSocket 客户端。 for more info about stompjsyou can download stomp.min.js file from here

    你应该下载 sockjs.min.js 和 stomp.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>
    
    • application-destination-prefix 用作按摩映射的前缀
    • path - 使用 http://localhost:8080/portfolio url 连接到 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) 事件发送的值。 (另外使用了 Angular 库来处理前端。tutorial for angular 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文件包含在按钮和进度条中。使用按钮启动服务器端事件(在本例中,按钮通过 Angular js 在AppController.java 中调用getValue() 函数。另外使用引导框架来创建前端。tutorial for 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 来自here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-20
      • 1970-01-01
      • 2015-11-01
      • 1970-01-01
      相关资源
      最近更新 更多