java search
Loading
Help improve Java Search

Wednesday, January 03, 2007

Making Simple POJO to Message Driven POJO with Spring

In the past, I posted a few examples of implementing Messaging using J2EE and Spring. This post will describe how to use the Spring MessageListenerAdapter to enable any Java class to act as a Message Driven POJO. This can be used to enable existing applications to use Asynchronous Messaging. Follow these steps to run the example:

The Message Driven POJO
  1. The following is the code for the Simple Java class that will be used as a Message Driven POJO
    public class MsgListener {
    public void receive(String message) {
    System.out.println("The message was : " + message);
    }
    }
    MsgListener.java
  2. The Spring Configuration used for this is shown below
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    <bean id="messageListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
    <constructor-arg>
    <bean class="jms.MsgListener" />
    </constructor-arg>
    <property name="defaultListenerMethod" value="receive" />
    <!-- we don't want automatic message context extraction -->
    <property name="messageConverter">
    <bean class="org.springframework.jms.support.converter.SimpleMessageConverter"></bean>
    </property>
    </bean>

    <!-- and this is the message listener container... -->
    <bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="concurrentConsumers" value="5" />
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="destination" ref="queue" />
    <property name="messageListener" ref="messageListener" />
    </bean>

    <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
    <props>
    <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
    <prop key="java.naming.provider.url">t3://localhost:20001</prop>
    </props>
    </property>
    </bean>
    <bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate">
    <ref bean="jndiTemplate" />
    </property>
    <property name="jndiName">
    <value>jms/connectionFactory</value>
    </property>
    </bean>

    <bean id="queue" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate">
    <ref bean="jndiTemplate" />
    </property>
    <property name="jndiName">
    <value>jms/testQueue</value>
    </property>
    </bean>
    </beans>
    WEB-INF/applicationContext.xml

    Note: The MessageListenerAdapter used here (bean-messageListener) is acts as an adapter to enable the MsgListener class to receive messages.
  3. The Web Deployment descriptor
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>SpringJMSWeb</display-name>
    <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    </web-app>
    web.xml

The Client
  1. Create a Simple Servlet that will be used to start the application. The code for the Servlet is shown below.
    public class QueueSenderServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext());
    QueueSender sender = (QueueSender)ctx.getBean("jmsSender");
    sender.sendMesage();
    }
    }
    QueueSenderServlet.java
  2. The following code shows Queue Sender. The Queue sender uses the JMSTemplate to send message to the queue.
    public class QueueSender {
    private JmsTemplate jmsTemplate;
    public void setJmsTemplate(JmsTemplate jmsTemplate) {
    this.jmsTemplate = jmsTemplate;
    }
    public void sendMesage() {
    jmsTemplate.send("jms/testQueue", new MessageCreator() {
    public Message createMessage(Session session) throws JMSException {
    return session.createTextMessage("Hello");
    }
    });
    }
    }
    QueueSender.java
  3. Spring Configuration: The Spring configuration file is shown below
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
    <props>
    <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
    <prop key="java.naming.provider.url">t3://localhost:20001</prop>
    </props>
    </property>
    </bean>

    <bean id="queueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate">
    <ref bean="jndiTemplate" />
    </property>
    <property name="jndiName">
    <value>jms/connectionFactory</value>
    </property>
    </bean>

    <bean id="jmsDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver">
    <property name="jndiTemplate">
    <ref bean="jndiTemplate" />
    </property>
    <property name="cache">
    <value>true</value>
    </property>
    </bean>

    <bean id="queueTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory">
    <ref bean="queueConnectionFactory" />
    </property>
    <property name="destinationResolver">
    <ref bean="jmsDestinationResolver" />
    </property>
    </bean>

    <bean id="jmsSender" class="jms.QueueSender">
    <property name="jmsTemplate">
    <ref bean="queueTemplate" />
    </property>

    </bean>
    </beans>
    WEB-INF/applicationContext.xml
  4. The Web Deployment descriptor
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>SpringJMSWeb</display-name>
    <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    </web-app>
    web.xml

2 comments:

  1. Hi Aabhi,

    Do I need a server for this?

    How do I invoke the web.xml and invoke the listener?

    Regards,
    Deep

    ReplyDelete
  2. Yeah, you'll need a JEE app server.

    ReplyDelete