2014-01-28 49 views
0

我正在嘗試爲JMS隊列創建POC。我使用spring mvc控制器作爲jms的客戶端。嘗試將異步偵聽器添加到MessageConsumer對象(代碼段)時出現以下錯誤。我讀過的地方只能將聽衆添加到MDB(消息驅動的bean),這是真的嗎?JMS - 將偵聽器添加到MessageConsumer時出錯

安裝程序:對於JMS使用websphere服務器總線。爲conn工廠,目的地等添加了jndi,以便同步操作一切正常。但是,對於異步,這是行不通的。

用於this用於設置JMS

[1/28/14 14:38:12:570 CST] 0000005d SystemErr  R javax.jms.IllegalStateException: CWSIA0084E: The method MessageConsu 
mer.setMessageListener is not permitted in this container. 
[1/28/14 14:38:12:572 CST] 0000005d SystemErr  R  at com.ibm.ws.sib.api.jms.impl.JmsMsgConsumerImpl._setMessageListen 
er(JmsMsgConsumerImpl.java:660) 
[1/28/14 14:38:12:573 CST] 0000005d SystemErr  R  at com.ibm.ws.sib.api.jms.impl.JmsMsgConsumerImpl.setMessageListene 
r(JmsMsgConsumerImpl.java:609) 

CODE:從Queue

public void connect(String hostName, String portNumber, 

    String connectionFactoryString, String consumerJNDIName) 

    throws Exception { 

     Hashtable env = new Hashtable(); 

     env.put(Context.PROVIDER_URL, "iiop://" + hostName + ":" + portNumber 
       + ""); 

     env.put(Context.INITIAL_CONTEXT_FACTORY, 
       "com.ibm.websphere.naming.WsnInitialContextFactory"); 

     InitialContext initialContext = new InitialContext(env); 

     ConnectionFactory connectionFactory = (ConnectionFactory) initialContext 
       .lookup(connectionFactoryString); 

     connection = connectionFactory.createConnection(); 

     connection.start(); 

     // create destination - JMSQueue 

     Destination destinationReceiver = (Destination) initialContext 
       .lookup(consumerJNDIName); 

     consumerSession = connection.createSession(false, 
       Session.AUTO_ACKNOWLEDGE); 

     consumer = consumerSession.createConsumer(destinationReceiver); 

     consumer.setMessageListener(new MessageListener() { **// ERROR here** 

      public void onMessage(Message msg) { 
       try { 
        System.out.println("received: " + ((TextMessage) msg).getText()); 
       } catch (JMSException ex) { 
        ex.printStackTrace(); 
       } 

      } 
     }); 
    } 
+0

什麼是您的WebSphere Application Server版本? –

+0

WS 6.1 – Zeus

+0

這是什麼意思 - 「對於異步,這不工作」? JMS本身就是異步協議。您實施的示例並非真正正確。你需要使用來自JMS隊列的消息嗎? –

回答

1

使用消息,你只需要在MessageListener註冊Spring context

web.xml你應該資源引用註冊JMS資源的內部應用服務器:

<resource-ref> 
    <res-ref-name>jms.jndi.cf.name</res-ref-name> 
    <res-type>javax.jms.ConnectionFactory</res-type> 
    <res-auth>Container</res-auth> 
    <res-sharing-scope>Shareable</res-sharing-scope> 
</resource-ref> 

<resource-ref> 
    <res-ref-name>jms.jndi.queue</res-ref-name> 
    <res-type>javax.jms.Queue</res-type> 
    <res-auth>Container</res-auth> 
    <res-sharing-scope>Shareable</res-sharing-scope> 
</resource-ref> 

下一步是Spring context

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee" 
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd 
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd 
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd"> 

<tx:annotation-driven/> 
<context:component-scan base-package="com.jms" /> 
    <!-- Connection Factory --> 
<jee:jndi-lookup id="myConnectionFactory" jndi-name="jms.jndi.cf.name" /> 

<!-- Queue --> 
<jee:jndi-lookup id="destination" jndi-name="jms.jndi.queue.name" /> 

<!-- JMS Destination Resolver --> 
<bean id="jmsDestinationResolver" class="org.springframework.jms.support.destination.DynamicDestinationResolver"> 
</bean> 

<!-- JMS Queue Template --> 
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate"> 
    <property name="connectionFactory"> 
     <ref bean="myConnectionFactory" /> 
    </property> 
    <property name="destinationResolver"> 
     <ref bean="jmsDestinationResolver" /> 
    </property> 
    <property name="pubSubDomain"> 
     <value>false</value> 
    </property> 
    <property name="receiveTimeout"> 
     <value>20000</value> 
    </property> 
</bean> 

<bean id="messageListener" class="com.jms.JMSMessageListener" /> 

<!-- Message listener container --> 
<bean id="jmsConsumerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> 
    <property name="connectionFactory" ref="myConnectionFactory" /> 
    <property name="destination" ref="destination" /> 
    <property name="messageListener" ref="messageListener" /> 

</bean> 
</beans> 

,最後一步是MessageListener

package com.jms; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.transaction.annotation.Transactional; 

import javax.jms.BytesMessage; 
import javax.jms.Message; 
import javax.jms.MessageListener; 
import java.io.ByteArrayInputStream; 
import java.io.StringReader; 

public class JMSMessageListener implements MessageListener { 

private static final Logger LOGGER = LoggerFactory.getLogger(JMSMessageListener.class); 

private static final String ENCODNG = "UTF-8"; 

@Transactional 
public void onMessage(Message message) { 
    if (message instanceof BytesMessage) { 
     try { 
      BytesMessage bytesMessage = (BytesMessage) message; 
      LOGGER.debug("Receive message from Queue:\n" + bytesMessage); 

      byte[] data = new byte[(int) bytesMessage.getBodyLength()]; 
      bytesMessage.readBytes(data); 
      String stringMessagePayload = new String(data, ENCODNG); 
      LOGGER.debug("Message payload: \n" + stringMessagePayload); 
      } 
     } catch (Exception ex) { 
      LOGGER.error("Error has occured: " + ex); 
      throw new RuntimeException(ex); 
     } 
    } else { 
     throw new IllegalArgumentException("Message must be of type BytesMessage"); 
    } 
} 
} 

我希望這個快速的例子將h elp你。

+0

Thanks.will試着讓你知道 – Zeus

+0

的一個問題。在web.xml中resourse-ref的意義是什麼? – Zeus

+0

意義在於:1)您的應用程序始終使用相同的資源名稱。 2)Application Server管理員可以隨意配置資源,配置它並映射它,而無需更改應用程序。這是簡單的j2ee資源管理規則。如果你已經處理了WebSphere和Spring,Hibernate庫,你應該仔細閱讀這篇文章 - http://www.ibm.com/developerworks/websphere/techjournal/0609_alcott/0609_alcott.html –