如何在 Spring Boot 应用程序中向 STOMP CREATED 消息添加自定义标头?
Posted
技术标签:
【中文标题】如何在 Spring Boot 应用程序中向 STOMP CREATED 消息添加自定义标头?【英文标题】:How to add custom headers to STOMP CREATED message in Spring Boot application? 【发布时间】:2017-06-29 05:16:55 【问题描述】:我正在尝试将自定义标头添加到客户端在第一次连接时收到的 STOMP 'CREATED' 消息。这是使用 STOMP javascript 连接到 WebSocket 的函数:
function connect()
socket = new SockJS('/chat');
stompClient = Stomp.over(socket);
stompClient.connect('', '', function(frame)
whoami = frame.headers['user-name'];
console.log(frame);
stompClient.subscribe('/user/queue/messages', function(message)
console.log("MESSAGE RECEIVED:");
console.log(message);
showMessage(JSON.parse(message.body));
);
stompClient.subscribe('/topic/active', function(activeMembers)
showActive(activeMembers);
);
);
此函数将以下内容打印到浏览器的控制台:
body: ""
command: "CONNECTED"
headers: Object
heart-beat: "0,0"
user-name: "someuser"
version: "1.1"
我想添加自定义标题,所以输出必须如下所示:
body: ""
command: "CONNECTED"
headers: Object
heart-beat: "0,0"
user-name: "someuser"
version: "1.1"
custom-header: "foo"
我的 Spring Boot 应用中有以下 WebSocket 配置。WebSocketConfig.java
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer
@Override
public void configureMessageBroker(MessageBrokerRegistry config)
config.enableSimpleBroker("/queue", "/topic");
config.setApplicationDestinationPrefixes("/app");
@Override
public void registerStompEndpoints(StompEndpointRegistry registry)
registry.addEndpoint("/chat", "/activeUsers")
.withSockJS()
.setInterceptors(customHttpSessionHandshakeInterceptor());
...
@Bean
public CustomHttpSessionHandshakeInterceptor
customHttpSessionHandshakeInterceptor()
return new CustomHttpSessionHandshakeInterceptor();
我尝试注册“HandshakeInterceptor”来设置自定义标头,但没有成功。这是“CustomHttpSessionHandshakeInterceptor”:CustomHttpSessionHandshakeInterceptor.java
public class CustomHttpSessionHandshakeInterceptor implements
HandshakeInterceptor
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response,
WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception
if (request instanceof ServletServerHttpRequest)
ServletServerHttpRequest servletRequest =
(ServletServerHttpRequest) request;
attributes.put("custom-header", "foo");
return true;
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response,
WebSocketHandler wsHandler,
Exception ex)
我在https://dzone.com/articles/spring-boot-based-websocket 找到了这个代码 sn-p 有人可以解释一下为什么这种方法不起作用吗?是否有另一种方法可以在 Spring Boot 应用程序的服务器端为 STOMP 'CREATED' 消息设置自定义标头? 谢谢!
【问题讨论】:
【参考方案1】:你试过这样吗? MessageHeaderAccessor 也有一个 setHeader 方法。 https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-authentication-token-based
【讨论】:
是的,我尝试使用 'MessageHeaderAccessor',它非常适用于带有 STOMP 'MESSAGE' 命令的消息(对于由使用 Spring 的'@MessageMapping' 注释并由'SimpMessagingTemplate'发送的方法处理的普通消息) '在我的情况下)。问题是如何使用 STOMP 'CONNECTED' 命令为消息添加自定义标头,该命令在建立 WebSocket 连接后由服务器发送?【参考方案2】:也许为时已晚,但迟到总比没有好......
服务器消息(例如 CONNECTED)是不可变的,意味着它们不能被修改。
我要做的是注册一个客户端出站拦截器并通过覆盖 preSend(...) 方法捕获连接的消息并使用我的自定义标头构建一个新消息。
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel)
LOGGER.info("Outbound channel pre send ...");
final StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message);
final StompCommand command = headerAccessor.getCommand();
if (!isNull(command))
switch (command)
case CONNECTED:
final StompHeaderAccessor accessor = StompHeaderAccessor.create(headerAccessor.getCommand());
accessor.setSessionId(headerAccessor.getSessionId());
@SuppressWarnings("unchecked")
final MultiValueMap<String, String> nativeHeaders = (MultiValueMap<String, String>) headerAccessor.getHeader(StompHeaderAccessor.NATIVE_HEADERS);
accessor.addNativeHeaders(nativeHeaders);
// add custom headers
accessor.addNativeHeader("CUSTOM01", "CUSTOM01");
final Message<?> newMessage = MessageBuilder.createMessage(new byte[0], accessor.getMessageHeaders());
return newMessage;
default:
break;
return message;
@UPDATE:::
所需的接口称为ChannelInterceptor
,要注册您自己的实现,您需要添加@Configuration
带注释的类
@Configuration
public class CustomMessageBrokerConfig extends WebSocketMessageBrokerConfigurationSupport
implements WebSocketMessageBrokerConfigurer
并覆盖一个方法 configureClientOutboundChannel 如下
@Override
public void configureClientOutboundChannel(ChannelRegistration registration)
log.info("Configure client outbound channel started ...");
registration.interceptors(new CustomOutboundChannelInterceptor());
log.info("Configure client outbound channel completed ...");
【讨论】:
对我来说,这个答案缺少很多支持方面。比如类应该长什么样,扩展了哪些类,实现了哪些接口,最后在哪里以及如何注册这个拦截器。如果这些在那里,我认为这将是一个很好的答案.. @RomeoSierra 我完全同意,这就像一个提示,而不是一个完整的答案。请在上面查看我的更新。 @TheReALDeAL 我在final StompCommand command = headerAccessor.getCommand();
得到了空值以上是关于如何在 Spring Boot 应用程序中向 STOMP CREATED 消息添加自定义标头?的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Boot 中向本机查询添加参数会导致“org.hibernate.exception.SQLGrammarException”,
dynamic-datasource-spring-boot-starter 简介中文文档中英对照文档 下载
如何在 spring-boot 中替换最新的 Jetty 9?
Spring Boot 轮播全屏 html,css,bootstrap
如何使用 Spring Boot 修改 HttpServletResponse 以在 json 中包含一些标准属性? [复制]