Our javascript websocket clients adds "custom" headers to all STOMP
messages.
My project handles websocket endpoints using spring-websocket @Controller
.
@MessageMapping(value = "/mymessages")
public void save(@Payload ToBeSaved payload, @Headers MessageHeaders headers) {
service.save(toMsg(payload, headers));
}
protected <P> Message<P> toMsg(P payload, MessageHeaders headers) {
return MessageBuilder.createMessage(payload, headers);
}
The controller modifies the payload and then passes the new payload and original websocket headers (including the custom ones) to a spring-integration @MessagingGateway
.
The underlying IntegrationFlow
tries to access the "custom" headers by accessing the message headers with the SPLExpression headers['custom']
.
Unfortunately headers['custom']
is always null because custom
is actually contained in the nativeHeaders
.
I haven't found a way to tell IntegrationFlow
to look into nativeHeaders
.
Is there a way in spring-websocket to copy all native headers as normal headers ?
Thanks in advance
The spring-websocket can do nothing for your on the matter. It isn't its responsibility.
If you would really like to have access to something in the nativeHeaders
, you should do that manually.
For your particular case that SpEL may look like:
headers['nativeHeaders']['custom']
Because nativeHeaders
is a Map
as well.
From other side you can use <header-enricher>
in your down stream flow to pop all those nativeHeaders
to top level.
And one more point: since Spring Integration 4.2
we provide native support for STOMP adapters. And there is a StompHeaderMapper
which does exactly what you want and the code there looks like:
else if (StompHeaderAccessor.NATIVE_HEADERS.equals(name)) {
MultiValueMap<String, String> multiValueMap =
headers.get(StompHeaderAccessor.NATIVE_HEADERS, MultiValueMap.class);
for (Map.Entry<String, List<String>> entry1 : multiValueMap.entrySet()) {
name = entry1.getKey();
if (shouldMapHeader(name, this.outboundHeaderNames)) {
String value = entry1.getValue().get(0);
if (StringUtils.hasText(value)) {
setStompHeader(target, name, value);
}
}
}
}