You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

订阅RESTful API并接收通知的实现问题求助

解决方案:实现API通知接收与实时页面展示

一、搭建SpringBoot通知接收端点

首先在SpringBoot中创建POST接口,用来接收1026服务器推送的通知(订阅类通知通常以POST方式推送),端口设置为你订阅时指定的1028。

示例代码:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class NotificationController {
    private static final Logger logger = LoggerFactory.getLogger(NotificationController.class);
    // 暂存最新实体数据,供前端获取
    private String latestEntityData;

    // 接收1026服务器推送的通知
    @PostMapping(value = "/notify", consumes = "application/json")
    public void receiveNotification(@RequestBody String notificationData) {
        logger.info("收到实体变更通知:{}", notificationData);
        latestEntityData = notificationData;
    }

    // 供前端获取最新数据的接口
    @GetMapping("/latest-entity")
    public String getLatestEntity() {
        return latestEntityData != null ? latestEntityData : "暂无数据";
    }
}

在application.properties中设置端口:

server.port=1028

二、完成API订阅逻辑

项目启动时调用订阅API,完成对1026服务器实体变更的订阅,替换原有的手动GET轮询逻辑。

示例代码:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

@Component
public class SubscriptionInitializer implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(SubscriptionInitializer.class);

    @Override
    public void run(String... args) throws Exception {
        // 订阅API地址,需根据实际API文档调整
        URL url = new URL("http://localhost:1026/v2/subscriptions");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setDoOutput(true);

        // 订阅请求体,按API要求构造,此处为示例
        String subscriptionBody = "{\"description\": \"订阅实体变更\", \"subject\": {\"entities\": [{\"idPattern\": \".*\"}]}, \"notification\": {\"http\": {\"url\": \"http://localhost:1028/notify\"}}}";

        try (OutputStream os = conn.getOutputStream()) {
            byte[] input = subscriptionBody.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        int responseCode = conn.getResponseCode();
        if (responseCode == 201) {
            logger.info("订阅成功");
        } else {
            logger.error("订阅失败,响应码:{}", responseCode);
        }
        conn.disconnect();
    }
}

三、实现页面实时展示

提供两种方案实现浏览器实时查看变更:

方案1:前端轮询(简单易实现)

前端定时调用/latest-entity接口获取最新数据:

<!DOCTYPE html>
<html>
<head>
    <title>实体实时监控</title>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
</head>
<body>
    <h3>最新实体数据:</h3>
    <pre id="entityData"></pre>

    <script>
        // 每2秒请求一次最新数据
        setInterval(() => {
            $.get("/latest-entity", function(data) {
                // 格式化JSON便于查看
                try {
                    data = JSON.stringify(JSON.parse(data), null, 2);
                } catch(e) {}
                $("#entityData").text(data);
            });
        }, 2000);
    </script>
</body>
</html>

方案2:WebSocket实时推送(低延迟)

如果需要更低延迟,用SpringBoot WebSocket实现主动推送:

  1. 添加WebSocket依赖到pom.xml:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
  1. 配置WebSocket:
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/entity-updates").withSockJS();
    }
}
  1. 修改NotificationController,收到通知时主动推送:
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.beans.factory.annotation.Autowired;
// ... 其他注解和代码

@RestController
public class NotificationController {
    private static final Logger logger = LoggerFactory.getLogger(NotificationController.class);
    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @PostMapping(value = "/notify", consumes = "application/json")
    public void receiveNotification(@RequestBody String notificationData) {
        logger.info("收到实体变更通知:{}", notificationData);
        // 推送到前端订阅的主题
        messagingTemplate.convertAndSend("/topic/entity-updated", notificationData);
    }
}
  1. 前端用Stomp.js接收推送:
<!DOCTYPE html>
<html>
<head>
    <title>实体实时监控</title>
    <script src="https://cdn.jsdelivr.net/npm/sockjs-client@1.5.2/dist/sockjs.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/stompjs@2.3.3/lib/stomp.min.js"></script>
</head>
<body>
    <h3>最新实体数据:</h3>
    <pre id="entityData"></pre>

    <script>
        const socket = new SockJS('/entity-updates');
        const stompClient = Stomp.over(socket);
        
        stompClient.connect({}, function(frame) {
            console.log('连接成功: ' + frame);
            stompClient.subscribe('/topic/entity-updated', function(message) {
                let data = message.body;
                try {
                    data = JSON.stringify(JSON.parse(data), null, 2);
                } catch(e) {}
                document.getElementById('entityData').textContent = data;
            });
        });
    </script>
</body>
</html>

四、替换原有GET逻辑

删除原有的手动GET轮询代码,改用上述订阅+通知接收的逻辑,无需再主动请求1026服务器,等待通知推送即可。


内容的提问来源于stack exchange,提问作者V.T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 11:10:20