STOMP header @MessageMapping return

STOMP header on @MessageMapping return

在我使用 Spring Websocket 的 Spring Boot 1.5 应用程序中,我想在 [=14] 的 return 值上设置自定义 STOMP header =] 方法,但我不知道该怎么做。例如:

@Controller
public class ChannelController {

    @MessageMapping("/books/{id}")
    public Book receive(@DestinationVariable("id") Long bookId) {
        return findBook(bookId);
    }

    private Book findBook(Long bookId) {
        return //...
    }
}

当客户的 STOMP SEND 触发 receive 时,我希望书本 body 的 STOMP MESSAGE 回复框架具有自定义 header: message-type:BOOK 像这样:

MESSAGE
message-type:BOOK
destination:/topic/books/1
content-type:application/json;charset=UTF-8
subscription:sub-0
message-id:0-7
content-length:1868

{ 
  "createdDate" : "2017-08-10T10:40:39.256", 
  "lastModifiedDate" : "2017-08-10T10:42:57.976", 
  "id" : 1, 
  "name" : "The big book", 
  "description" : null 
}
^@

如何为 @MessageMapping 中的回复 return 值设置 STOMP header?

您可以试试这个解决方案:

@MessageMapping("/books/{id}")
public GenericMessage<Book> receive(@DestinationVariable("id") Long bookId) {
    Map<String, List<String>> nativeHeaders = new HashMap<>();
    nativeHeaders.put("message-type", Collections.singletonList("BOOK"));

    Map<String, Object> headers = new HashMap<>();
    headers.put(NativeMessageHeaderAccessor.NATIVE_HEADERS, nativeHeaders);

    return new GenericMessage<Book>(findBook(bookId), headers);
}

如果 return 值签名不重要,您可以使用 SimpMessagingTemplate 正如@Shchipunov 在他的回答评论中指出的那样:

@Controller
@AllArgsConstructor
public class ChannelController {

    private final SimpMessagingTemplate messagingTemplate; 

    @MessageMapping("/books/{id}")
    public void receive(@DestinationVariable("id") Long bookId, SimpMessageHeaderAccessor accessor ) {
        accessor.setHeader("message-type", "BOOK");

        messagingTemplate.convertAndSend(
            "/topic/books/" + bookId, findBook(bookId), accessor.toMap()
        );
    }

    private Book findBook(Long bookId) {
        return //...
    }
}

正确序列化到问题中的 MESSAGE 帧。