I just wanted to include some cool websocket stuff within my project. This kinda worked out of the box! Thank you!!
I use SimpMessagingTemplate
for sending messages. They get automatically converted to JSON, which is nice, BUT I can't figure out which ObjectMapper
is getting used for this, because it won't use my custom Serializers and it also doesn't use my custom Jackson settings from application.properties.
Should I just use @Autowired ObjectMapper
and serialize my Objects to String by myself?
Btw: I didn't test if it uses the correct ObjectMapper
for JSON messages from the client to the server.
Comment From: philwebb
I think this might be one that we've missed. Are you currently using the @EnableWebSocketMessageBroker
annotation? I think that AbstractMessageBrokerConfiguration.createJacksonConverter()
is the method that adds a MappingJackson2MessageConverter
which by default will add a new ObjectMapper
.
The easiest work around for now is probably to add a AbstractWebSocketMessageBrokerConfigurer
bean and implements configureMessageConverters
to add your own MappingJackson2MessageConverter
with a fully configured ObjectMapper
.
Comment From: philwebb
@wilkinsona Do you think we should configure the MappingJackson2MessageConverter
ObjectMapper
in the same way as we do for MVC?
Comment From: wilkinsona
Yes. I think we should automatically configure any ObjectMapper that isn't created by the user.
Comment From: benneq
Will this be part of 1.2.2 ?
Comment From: wilkinsona
We don't have any auto-configuration that switches on @EnableWebSocketMessageBroker
at the moment so this may be too big a change for 1.2.2. It would be useful to know how you're currently configuring this. As Phil asked:
Are you currently using the @EnableWebSocketMessageBroker annotation?
It would also be useful to know if you're already extending AbstractWebSocketMessageBrokerConfigurer
as that would likely turn off any auto-configuration that we may add.
Comment From: benneq
Yes, I'm using simply
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { ... }
I use AbstractWebSocketMessageBrokerConfigurer because I need to set the Endpoint and the Prefixes.
EDIT: I now use this code. Is this the right way?
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Autowired ObjectMapper objectMapper;
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry
.addEndpoint("/stomp").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry
.setApplicationDestinationPrefixes("/app")
.setUserDestinationPrefix("/user")
.enableSimpleBroker("/queue", "/topic");
}
@Override
public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
DefaultContentTypeResolver resolver = new DefaultContentTypeResolver();
resolver.setDefaultMimeType(MimeTypeUtils.APPLICATION_JSON);
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setObjectMapper(objectMapper);
converter.setContentTypeResolver(resolver);
messageConverters.add(converter);
return false;
}
}
Comment From: wilkinsona
Yes, that's the kind of approach I would take.
Comment From: Polve
I stumbled here because I was trying to configure the mapper using this way:
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.(...);
return builder
}
but I now understand that the mapper is not used for converting messages.
Having the capability to configure it in the same way of the http converter (even inside application.properties) would be very handy and intuitive.
Comment From: msgilligan
I just stumbled upon this. One of the big selling points of Spring STOMP messaging is that you can use the same controller code for both REST and WebSocket/STOMP. Anyone doing this is going to want the same converters in both places.
NOTE: The workaround provided by @benneq above worked for me. Let me know when there's a snapshot that I can help test.
Comment From: xak2000
Just now stumbled upon this. All date-fields in objects are wrong serialized when sending to websocket as ObjectMapper ignores spring.jackson.serialization.write-dates-as-timestamps=false
property from my application.properties
.
Big thanks to @benneq for a workaround.
Comment From: joshdanhall
The solution provided by @benneq can be abbreviated to the following if all you want to do is customise the ObjectMapper. The configuration in WebSocketMessageConverterConfiguration still takes place so the other scaffolding in the configureMessageConverters() method is not required to be re-implemented. In fact, in my case because I'm on a newer version of SpringBoot (1.4.3), the code in the above sample is out of date, so it's better to leave spring do it's thing rather than copying/pasting it's implementation of configureMessageConverters().
The trick is in the fact that the auto-wired ObjectMapper will be the same instance that is used in WebSocketMessageConverterConfiguration.
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Autowired
private ObjectMapper objectMapper;
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket").setAllowedOrigins("*");
}
@Override
public boolean configureMessageConverters(
List<MessageConverter> messageConverters) {
// configure objectMapper here...
this.objectMapper.addMixIn(Foo.class, AbstractFooMixin.class);
return false;
}
}
Comment From: Polve
@joshdanhall What if WebSocketConfig extends WebSocketMessageBrokerConfigurationSupport instead?
Comment From: joshdanhall
I guess that might be an another approach, although as WebSocketMessageBrokerConfigurationSupport doesn't implement WebSocketMessageBrokerConfigurer, I'm not sure how to wire it up...