如何指定Spring Messaging中处理程序生成的内容类型?

时间:2014-01-27 20:15:44

标签: spring websocket stomp spring-messaging spring-websocket

我正在试验Spring 4 WebSocket STOMP应用程序。有没有办法显式指定处理程序生成的返回消息的内容类型?默认情况下,下面的处理程序生成application/json并由相应的消息转换器处理。

@Controller
public class ProductController {

    @MessageMapping("/products/{id}")
    public String getProduct(@DestinationVariable int id) {
        return getProductById(id);
    }

}

我在Spring MVC中寻找像@RequestMapping(produces = "text/xml")这样的东西。

更新(回复Rossen's answer):

理想情况下,我希望能够根据用户要求返回两种格式。但是如果我必须选择,我会说XML而且几乎从不JSON(XML只是一个例子,我们使用二进制格式)。我采用了你建议的第二种方式 - 配置自定义转换器而不是默认转换器。

  1. 我已实施自定义MessageConverter扩展AbstractMessageConverter。在构造函数中,我已经注册了适当的支持MimeType。
  2. 然后我通过覆盖WebSocketMessageBrokerConfigurer的{​​{1}}来注册我的自定义转换器,并从方法返回configureMessageConverters以不添加默认转换器。
  3. 一旦我的控制器返回值,我就会在false的{​​{1}}中获得NPE。发生这种情况是因为SendToMethodReturnValueHandler只包含一个转换器 - 我的自定义转换器。但我的转换器未通过postProcessMessage的{​​{1}}检查,CompositeMessageConverter的{​​{1}}返回AbstractMessageConverter。此supportsMimeType会导致AbstractMessageConverter中的例外。
  4. 作为解决方法,我可以为自定义转换器注册其他默认MimeType toMessage。但它对我来说太脏了。

2 个答案:

答案 0 :(得分:0)

没有像生产条件那样的东西。现在执行此操作的唯一方法是注入SimpMessagingTemplate,然后使用带有MessagePostProcessor的convertAndSend方法变体。它可以变得更简单。你的用例是什么?您是否主要使用JSON并且需要在几个地方使用XML?或者您是否需要主要使用XML?如果是后者,您只需将转换器配置为使用而不是默认转换器。

答案 1 :(得分:0)

我看到您可以更改标题,更改邮件转换器。 例如:

SockJsClient sockJsClient = new SockJsClient(transports);
WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient);
..
stompClient.setMessageConverter(new StringMessageConverter());
or
stompClient.setMessageConverter(new SimpleMessageConverter());

当您使用StringMessageConverter时,Java客户端会添加内容类型标头。

GenericMessage [payload=byte[33], headers={simpMessageType=MESSAGE, stompCommand=SEND, nativeHeaders={destination=[/app/chatchannel], content-type=[text/plain;charset=UTF-8], content-length=[33]}, simpSessionAttributes={ip=/127.0.0.1:59629}, simpHeartbeat=[J@147a2bf, contentType=text/plain;charset=UTF-8, lookupDestination=/chatchannel, simpSessionId=79431feb8b5f4a9497492ccc64f8965f, simpDestination=/app/chatchannel}]

但是如果使用SimpleMessageConverter,则不会添加内容类型标题。

这是关于你想做什么的线索?

检查这个问题,我提供了一些可以帮助你的代码:

How configure the Spring Sockjs Java Client message converters