Spring WebSocket JSON解析失败:Unrecognized token 'object'问题排查
问题解决:Stomp消息JSON解析失败
核心问题
前端sendMessage函数中stompClient.send的参数顺序不符合Stomp规范,导致JSON消息体被错误当作headers传递,后端收到无效的"[object Object]"内容,触发JSON解析异常。
修正后的前端代码
const sendMessage = (content) => { if (stompClient) { const message = [{ content: content, sender: 'user' }]; // 修正参数顺序:第二个参数为headers(传空对象),第三个为消息体JSON字符串 stompClient.send( '/app/websocket', {}, // 正确的headers位置,无额外头信息时传空对象 JSON.stringify(message) ); console.log(JSON.stringify(message)); } else { console.error('Stomp client is not initialized.'); } };
错误原因说明
Stomp客户端send方法的标准签名为:
stompClient.send(destination, headers, messageBody);
- 第一个参数:消息目标地址
- 第二个参数:消息头(必须是对象类型,无额外需求时传空对象
{}) - 第三个参数:消息体(JSON字符串格式)
原代码将JSON.stringify(message)放在第二个参数位置,Stomp客户端会将非对象类型的headers参数默认处理为[object Object],导致后端收到的消息体完全无效,无法被Jackson解析,最终抛出MessageConversionException。
佐证信息
前端发送的错误Frame格式
frame: body: {} command: "SEND" headers: 0: "[" 1: "{" 2: "\"" 3: "c" 4: "o" 5: "n" 6: "t" 7: "e" 8: "n" 9: "t" 10: "\"" 11: ":" 12: "\"" 13: "g" 14: "o" 15: "\"" 16: "," 17: "\"" 18: "s" 19: "e" 20: "n" 21: "d" 22: "e" 23: "r" 24: "\"" 25: ":" 26: "\"" 27: "u" 28: "s" 29: "e" 30: "r" 31: "\"" 32: "}" 33: "]" destination: "/app/websocket"
后端错误日志
org.springframework.messaging.converter.MessageConversionException: Could not read JSON: Unrecognized token 'object': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false') at [Source: (byte[])\"[object Object]\"; line: 1, column: 9] at org.springframework.messaging.converter.MappingJackson2MessageConverter.convertFromInternal(MappingJackson2MessageConverter.java:255) ~[spring-messaging-6.1.2.jar:6.1.2] at org.springframework.messaging.converter.AbstractMessageConverter.fromMessage(AbstractMessageConverter.java:183) ~[spring-messaging-6.1.2.jar:6.1.2] at org.springframework.messaging.converter.CompositeMessageConverter.fromMessage(CompositeMessageConverter.java:70) ~[spring-messaging-6.1.2.jar:6.1.2] at org.springframework.messaging.handler.annotation.support.PayloadMethodArgumentResolver.resolveArgument(PayloadMethodArgumentResolver.java:144) ~[spring-messaging-6.1.2.jar:6.1.2] at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:118) ~[spring-messaging-6.1.2.jar:6.1.2] at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:147) ~[spring-messaging-6.1.2.jar:6.1.2] at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:115) ~[spring-messaging-6.1.2.jar:6.1.2] at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:567) ~[spring-messaging-6.1.2.jar:6.1.2] at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:511) ~[spring-messaging-6.1.2.jar:6.1.2] at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:93) ~[spring-messaging-6.1.2.jar:6.1.2] at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:522) ~[spring-messaging-6.1.2.jar:6.1.2] at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:457) ~[spring-messaging-6.1.2.jar:6.1.2] at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:144) ~[spring-messaging-6.1.2.jar:6.1.2] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na] Caused by: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'object': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false') at [Source: (byte[])\"[object Object]\"; line: 1, column: 9] at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:2477) ~[jackson-core-2.15.3.jar:2.15.3] at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:760) ~[jackson-core-2.15.3.jar:2.15.3] at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._reportInvalidToken(UTF8StreamJsonParser.java:3699) ~[jackson-core-2.15.3.jar:2.15.3] at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._handleUnexpectedValue(UTF8StreamJsonParser.java:2787) ~[jackson-core-2.15.3.jar:2.15.3] at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._nextTokenNotInObject(UTF8StreamJsonParser.java:908) ~[jackson-core-2.15.3.jar:2.15.3] at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:794) ~[jackson-core-2.15.3.jar:2.15.3] at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:350) ~[jackson-databind-2.15.3.jar:2.15.3] at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244) ~[jackson-databind-2.15.3.jar:2.15.3] at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:28) ~[jackson-databind-2.15.3.jar:2.15.3] at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323) ~[jackson-databind-2.15.3.jar:2.15.3] at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4825) ~[jackson-databind-2.15.3.jar:2.15.3] at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3866) ~[jackson-databind-2.15.3.jar:2.15.3] at org.springframework.messaging.converter.MappingJackson2MessageConverter.convertFromInternal(MappingJackson2MessageConverter.java:241) ~[spring-messaging-6.1.2.jar:6.1.2] ... 15 common frames omitted
后端Controller代码(无需修改)
@Controller public class ChatController { @MessageMapping("/websocket") @SendTo("/topic/messages") public List<ChatMessage> send(@Payload List<ChatMessage> message) throws Exception { System.out.println("hi"); Thread.sleep(1000); // simulated delay return message; } }
内容的提问来源于stack exchange,提问作者kimgaeul
相关产品推荐
相关产品推荐

