订阅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实现主动推送:
- 添加WebSocket依赖到
pom.xml:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
- 配置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(); } }
- 修改
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); } }
- 前端用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
相关产品推荐
相关产品推荐

