如何通过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
相关产品推荐
相关产品推荐

