使用从AMQP到STOMP消息的contentType有问题

时间:2015-02-18 15:29:20

标签: spring spring-integration spring-amqp spring-websocket

这是我的(总结)

<int-amqp:inbound-channel-adapter 
    auto-startup="false" 
    listener-container="clientListenerContainer" 
    channel="fromRabbitClientChannel" 
    connection-factory="rabbitConnectionFactory" />

<bean id="clientListenerContainer" class="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer">
    <property name="connectionFactory" ref="rabbitConnectionFactory" />
</bean>

<int:service-activator ref="subscriptionHandler" method="convertMessage" input-channel="fromRabbitClientChannel" output-channel="sendMessage" />

<bean id="stompSubProtocolHandler" class="org.springframework.web.socket.messaging.StompSubProtocolHandler"/>

<int-websocket:outbound-channel-adapter channel="sendMessage" 
                                            container="serverWebSocketContainer"
                                            default-protocol-handler="stompSubProtocolHandler"/>

这是我的subscriptionHandler convertMessage函数

public Message convertMessage(Message message){
    String subscriptionQuery = AmqpMessageHeaderAccessor.wrap(message).getReceivedRoutingKey();
    ClientSubscription subscription = this.subscriptions.getBySubscriptionQuery(subscriptionQuery);

    Message msg = MessageBuilder.withPayload(message.getPayload())
            .setHeader(SimpMessageHeaderAccessor.SESSION_ID_HEADER, subscription.getSessionId())
            .setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, subscription.getSubscriptionQuery())
            .setHeader(SimpMessageHeaderAccessor.SUBSCRIPTION_ID_HEADER, subscription.getSubscriptionId()).build();
    return msg;
}

当消息通过<int-amqp:inbound-channel-adapter>SimpleMessageListenerContainer和我的''进入时,有效负载是byte [],而contentType标头设置为application / octet-stream。

然后我的convertMessage函数使用一些STOMP头从有效负载创建一条消息,并将其返回到stompSubProtocolHandler接管的sendMessage通道。它在那里,当它试图将头转换为stomp消息时,抛出异常java.lang.String不能转换为org.springframework.util.MimeType。

这是堆栈跟踪。

Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to org.springframework.util.MimeType
    at org.springframework.messaging.support.MessageHeaderAccessor.getContentType(MessageHeaderAccessor.java:457)
    at org.springframework.messaging.simp.stomp.StompHeaderAccessor.updateStompHeadersFromSimpMessageHeaders(StompHeaderAccessor.java:169)
    at org.springframework.messaging.simp.stomp.StompHeaderAccessor.<init>(StompHeaderAccessor.java:127)
    at org.springframework.messaging.simp.stomp.StompHeaderAccessor.wrap(StompHeaderAccessor.java:478)
    at org.springframework.web.socket.messaging.StompSubProtocolHandler.getStompHeaderAccessor(StompSubProtocolHandler.java:402)
    at org.springframework.web.socket.messaging.StompSubProtocolHandler.handleMessageToClient(StompSubProtocolHandler.java:329)
    at org.springframework.integration.websocket.outbound.WebSocketOutboundMessageHandler.handleMessageInternal(WebSocketOutboundMessageHandler.java:151)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)

我觉得我没有添加我需要的标题,或者我可能需要使用消息转换器...或者我可能只是没有正确地做到这一点。

我需要对消息进行哪些操作才能为stompSubProtocolHandler做好准备?

我是否使用<int-amqp:inbound-channel-adapter> SimpleMessageListenerContainer正确处理来自AMQP的邮件? (我需要容器在更多订阅时动态添加更多队列)

1 个答案:

答案 0 :(得分:2)

虽然好的任务!

您是否愿意将它作为社区的样本分享? 作为此项目的PullRequest:https://github.com/spring-projects/spring-integration-samples

由于您的StackTrace表示contentTypeString,您可以在subscriptionHandler中覆盖它:

AmqpMessageHeaderAccessor amqpMessageHeaderAccessor = AmqpMessageHeaderAccessor.wrap(message);
....
.setHeader(MessageHeaders.CONTENT_TYPE, amqpMessageHeaderAccessor.getContentType())

<强>更新

顺便说一句,我们最近解决了contentType歧义:https://jira.spring.io/browse/SPR-12730。使用最新的SF 4.1.5,您无需再关注contentType转换了。它在框架中自动完成。