Spring Boot 1.3 WebSocket JSON 转换器产生无效的 JSON

Posted

技术标签:

【中文标题】Spring Boot 1.3 WebSocket JSON 转换器产生无效的 JSON【英文标题】:Spring Boot 1.3 WebSocket JSON converter Produces Invalid JSON 【发布时间】:2016-05-20 23:55:23 【问题描述】:

升级到 Spring Boot 1.3(通过 Grails 3.1)后,JSON 输出呈现不正确。我相信是因为new auto-configured WebSocket JSON converter。

例如,对于以前版本的 Spring Boot(通过 Grails 3.0),使用以下代码:

@MessageMapping("/chat")
@SendTo("/sub/chat")
protected String chatMessage() 
    def builder = new groovy.json.JsonBuilder()
    builder 
        type("message")
        text("foobar")
    
    builder.toString()

这会产生:

"type": "message", "text": "foobar"

使用 Spring Boot 1.3(通过 Grails 3.1),该 Web 套接字生成以下内容:

"\"type\":\"message\",\"text\":\"foobar\""

这不是有效的 JSON。如何摆脱这种新行为并让它像以前一样呈现 JSON?如果您有任何建议,请告诉我。

我尝试覆盖新的configureMessageConverters 方法,但没有任何效果。

【问题讨论】:

我已经打开github.com/spring-projects/spring-boot/issues/5123 【参考方案1】:

看起来你是对的。引用的提交显示有问题的自动配置恕我直言。

尤其是过去的b/c,转换器排序被故意更改为StringMessageConverter优先于MappingJackson2MessageConverter:https://github.com/spring-projects/spring-framework/commit/670c216d3838807fef46cd28cc82165f9abaeb45

现在,您可以禁用该自动配置:

@EnableAutoConfiguration(exclude = [WebSocketMessagingAutoConfiguration])
class Application extends GrailsAutoConfiguration  ... 

或者,您将另一个 StringMessageConverter 添加到已配置转换器的顶部(可能是因为您确实需要启动自动配置行为,因为它使用的是 jackson ObjectMapper bean 而不是创建新的):

@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer 

    @Override
    boolean configureMessageConverters(List<MessageConverter> messageConverters) 
        messageConverters.add 0, new StringMessageConverter()
        return true
    

...


希望有帮助。

【讨论】:

【参考方案2】:

我不知道如何在 Grails 中执行此操作,但在 Java 中,您现在必须传递对象而不是 String 类中的对象。我相信旧的行为实际上是不正确的,因为它将字符串作为对象返回,因此无法返回其中包含 JSON 作为字符串的字符串。所以用你想要的结构创建一个对象并返回它,你应该没问题。从 1.2.X 升级到 1.3.X 时,我遇到了同样的问题。我不确定是什么变化导致了这种情况,但我认为从长远来看这是正确的做法。

【讨论】:

以上是关于Spring Boot 1.3 WebSocket JSON 转换器产生无效的 JSON的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring-boot 中路由 websocket 目标

Spring Boot - WebSocket 握手期间出错

玩转spring boot——websocket

Spring Boot之WebSocket

Spring boot + Websocket

Spring Boot教程32——WebSocket