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

如何通过WebClient从SSE消息中获取ID与事件值并反序列化

解决WebClient接收SSE时获取消息ID、事件类型并反序列化的问题

核心问题分析

你当前用bodyToFlux(String.class)会把整个SSE消息块当成纯文本,无法拆分出id、event和data字段。Spring WebClient支持直接绑定到org.springframework.http.codec.ServerSentEvent类,它会自动解析SSE的各个组成部分。

客户端修改方案

1. 改用ServerSentEvent接收消息

将bodyToFlux(String.class)替换为bodyToFlux(ServerSentEvent.class),这样就能直接获取id、event(事件类型)和data(原始JSON字符串)。

2. 根据事件类型反序列化数据

服务器端的event字段是实体类的类名(比如TypeA、TypeB),可以维护一个类名到Class的映射,再用Jackson工具把JSON字符串反序列化成对应的实体类。

修改后的客户端代码

import org.springframework.http.codec.ServerSentEvent;
import com.fasterxml.jackson.databind.ObjectMapper;

// 初始化WebClient和ObjectMapper
final WebClient wc = WebClient.builder()
        .baseUrl("https://example.sk/")
        .build();
ObjectMapper objectMapper = new ObjectMapper();

// 维护类名到实体类的映射
Map<String, Class<? extends MyInterfaceForThreeDifferentTypes>> eventTypeMap = new HashMap<>();
eventTypeMap.put("TypeA", TypeA.class);
eventTypeMap.put("TypeB", TypeB.class);
eventTypeMap.put("TypeC", TypeC.class);

wc.get().uri("sseEndpoint")
        .retrieve()
        .bodyToFlux(ServerSentEvent.class)
        .subscribe(sse -> {
            // 获取消息ID
            String messageId = sse.id();
            // 获取事件类型(类名)
            String eventType = sse.event();
            
            // 根据事件类型反序列化数据
            if (eventType != null && eventTypeMap.containsKey(eventType)) {
                try {
                    MyInterfaceForThreeDifferentTypes data = objectMapper.readValue(
                        sse.data().toString(), 
                        eventTypeMap.get(eventType)
                    );
                    // 处理反序列化后的对象
                    System.out.println("消息ID: " + messageId);
                    System.out.println("事件类型: " + eventType);
                    System.out.println("处理数据: " + data);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

补充说明

  • 确保实体类TypeA、TypeB、TypeC都实现了MyInterfaceForThreeDifferentTypes接口,这样统一接收后可进行多态处理。
  • 若Spring WebClient的Jackson配置已自定义,可直接使用框架提供的ObjectMapper,无需自行实例化。

内容的提问来源于stack exchange,提问作者Lubo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 09:15:58