如何在Spring Boot应用程序中向STOMP创建的消息添加自定义头?

如何在Spring Boot应用程序中向STOMP创建的消息添加自定义头?,spring,spring-boot,websocket,stomp,spring-websocket,Spring,Spring Boot,Websocket,Stomp,Spring Websocket,我试图将自定义头添加到STOMP“CREATED”消息中,该消息由客户端在第一次连接时接收。下面是使用STOMP JavaScript连接到WebSocket的函数: function connect() { socket = new SockJS('/chat'); stompClient = Stomp.over(socket); stompClient.connect('', '', function(frame) { whoami = frame.he

我试图将自定义头添加到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();

  }

}
我尝试注册“握手接收器”来设置自定义标题,但没有成功。这是“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) { }
}
公共类CustomHttpSessionHandshakeInterceptor实现
握手接受器{
@凌驾
握手前公共布尔值(ServerHttpRequest请求,
ServerHttpResponse响应,
WebSocketHandler wsHandler,
映射属性)引发异常{
if(ServletServerHttpRequest的请求实例){
ServletServerHttpRequest servletRequest=
(ServletServerHttpRequest)请求;
attributes.put(“自定义标题”、“foo”);
}
返回true;
}
握手后公共无效(ServerHttpRequest请求,
ServerHttpResponse响应,
WebSocketHandler wsHandler,
例外情况ex){}
}
我在上找到了这个代码段
有人能解释一下为什么这种方法不起作用吗?在Spring Boot应用程序中,是否有其他方法可以在服务器端为STOMP“CREATED”消息设置自定义头?

谢谢

你是这样试的吗?MessageHeaderAccessor也有一个setHeader方法。
也许太晚了,但迟做总比不做好

服务器消息(如连接的)是不可变的,这意味着它们不能被修改

我要做的是注册一个客户端出站拦截器,通过覆盖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;
    }
并重写方法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 ...");
}

是的,我尝试使用“MessageHeaderAccessor”,它非常适用于带有STOMP“MESSAGE”命令的消息(在我的例子中,普通消息由Spring的“@MessageMapping”注释的方法处理,并由“SimpMessageTemplate”发送)。问题是如何使用STOMP'CONNECTED'命令为消息添加自定义标题,该命令是在建立WebSocket连接后由服务器发送的?对我来说,这个答案缺少很多支持方面。例如,类应该是什么样子,扩展了哪些类,实现了哪些接口,最后是在何处以及如何注册这个拦截器。如果有这些,我想这将是一个很好的答案。@RomeoSierra我完全同意,这只是一个暗示,而不是一个完整的答案。请看我上面的更新。@TheAlDeal我在
final StompCommand=headerAccessor.getCommand()处得到空值
@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {
    log.info("Configure client outbound channel started ...");
    registration.interceptors(new CustomOutboundChannelInterceptor());
    log.info("Configure client outbound channel completed ...");
}