Showing posts with label SpringFramework. Show all posts
Showing posts with label SpringFramework. Show all posts

Tuesday, March 15, 2011

Messaging With WebSphere MQ Using Spring JMS

Spring JMS provides a simple API to work with JMS implementations. This post describes how to use Spring JMS to communicate with IBM WebSphere MQ. The code has been tested with WebSphere MQ version 7.0.1. Maven is used as the build tool. It is also used to resolve the WebSphere MQ and other dependencies. Only relevant code snippets are listed below - for the complete source, please refer to the link at the bottom of this post.

To start off we need to obtain the WebSphere MQ JARs. These JARs are proprietary - hence they will not resolve through a public Maven repository like Maven Central. These JARs need to be obtained from the WebSphere MQ installation directory and manually deployed to our local Maven repository. The config below defines the WebSphere MQ dependencies in our Maven POM file.

Spring's JMSTemplate class is the key to simplifying access to the conventional JMS API. It abstracts the common and repetitive boiler-plate code by handling the creation and closing of connections and sessions, sending and receiving of messages and handling of exceptions. JMSTemplate and a few other beans need to be defined in our Spring config.

MQQueueConnectionFactory defines the connection to the Queue Manager. Next we define SingleConnectionFactory102, DynamicDestinationResolver and finally JmsTemplate102. The 102 suffix implies that our underlying JMS implementation version is 1.0.2. Now that our configuration is complete, we can send and receive JMS messages.

To send a JMS message, we use the send(String destinationName, MessageCreator creator) method of JMSTemplate.

To receive a message, we use the receive(String destinationName) method.

As we can see, Spring's JMSTemplate really simplifies and speeds-up connecting to a JMS provider like WebSphere MQ.

Sample Source Code
A fully functional example Maven application accompanies this post. It provides the complete source code mentioned in this post. It can be downloaded at GitHub using the link below.

Thursday, April 26, 2007

Long-running Processes with Spring DAO and Hibernate

Spring and Hibernate are increasingly used together in Java web applications. Spring is used as the MVC and dependency-injection framework and also provides support for data access, transaction management etc. Hibernate is usually used alongside Spring as the object-relational mapping framework. Spring's support for Hibernate is impressive through it's DAO templating mechanism. This truly simplifies matters as all the routine infrastructure plumbing code is taken care of by Spring.

Spring intercepts requests made to the webapp and through dependency-injection makes objects available in order to fulfil the request. This includes creating the Hibernate Session object used by the DAOs. The Session object is lightweight and created and destroyed for every request. Hibernate sessions are not threadsafe and should be used by only one thread at a time. In order to keep the session open throughout the lifetime of a request we tie it to the view. This is done either by using Spring's OpenSessionInViewInterceptor or OpenSessionInViewFilter as below:

<bean id="openSessionInViewInterceptor" 
    class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
    <property name="sessionFactory" ref="sessionFactory" />
    <property name="flushModeName" value="Flush_AUTO" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    ...
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    ...
</bean>

Most requests are synchronous and completed before the response is returned to the client. However, in the case of long-running processes, a new thread is created for execution of the process. The response is returned back to the client and the process runs independently on the server. Hibernate sessions obtained through OpenSessionInViewInterceptor are no longer available to the process as they are closed once the view has returned. This throws a LazyInitializationException complaining that the owning session was closed.

The problem can be overcome by directly accessing the Hibernate SessionFactory bean and binding the session to the long-running process thread. Hence the session is available and open within the thread itself. The UML diagram below describes our objects.

TestController is the Controller class that handles the request. Since it implements the ServletContextAware interface, Spring automatically passes the ServletContext object to it. This is used to obtain the ApplicationContext object. Next we create an instance of our LongProcessInvoker class, pass ApplicationContext to it and finally start execution using an Executor.

// TestController.java
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
    try {
        ApplicationContext ac = 
            WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
            
        LongProcessInvoker lpi = new LongProcessInvoker();
        lpi.setApplicationContext(ac);
            
        Executor ex = Executors.newSingleThreadExecutor();
        ex.execute(lpi);
    }
    catch(...) {
        ...
    }
}

In LongProcessInvoker we obtain the Session using SessionFactoryUtils and bind it to the current thread. Next the long running process is invoked and once complete we execute some clean-up code by releasing and closing the Session.

// LongProcessInvoker.java
public void run() {
    try {
        // Bind session object. 
        SessionFactory sessionFactory = 
            (SessionFactory) applicationContext.getBean("sessionFactory");
        Session session = SessionFactoryUtils.getSession(sessionFactory, true);
        TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));        
        
        LongProcess lp = (LongProcess) applicationContext.getBean("longProcess");
        lp.runLongProcess();
        
        // Release session object.
        session.flush();
        TransactionSynchronizationManager.unbindResource(sessionFactory);
        SessionFactoryUtils.closeSession(session);
    }
    catch(...) {
        ...
    }
}

Using the above approach, we can now run long-running processes by obtaining the Hibernate session outside the view.

Wednesday, September 13, 2006

Spring MVC and AJAX with JSON

One of the main decisions to be taken while developing AJAX applications is the format of messages passed by the server to the client browser. There are many options to choose from including plain text, XML, CSV etc. One of the more popular choices today is the JavaScript Object Notation (JSON). JSON provides a nice name-value pair data format that is easy to generate and parse. This is especially true when using an AJAX toolkit like Dojo that provides built-in functionality to parse JSON messages at the client. If you are using Spring MVC as your web framework, generation of these JSON messages is very straight-forward as well. Below we understand how to produce JSON messages while using Spring MVC.

Spring MVC defines the View interface to render views to the client. The framework provides a number of implementations including JstlView, RedirectView, TilesView etc. In order to return JSON messages we implement the View interface to create a new class that returns data formatted using the JSON notation. We shall call this class JSONView.

The method that we need to implement is render(Map model, HttpServletRequest request, HttpServletResponse response). The render method accepts a Map as it's first parameter and produces the output. We could manually iterate through the Map, process and produce the JSON output. However, there is a Java library called JSON-lib that produces the JSON notation. The code below shows our JSONView class that can be used as a Spring MVC View to return JSON output to the client.

import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import org.springframework.web.servlet.View;
 
public class JSONView implements View {
    public void render(Map map, HttpServletRequest request,
    HttpServletResponse response) throws Exception {
        JSONObject jsonObject = JSONObject.fromMap(map);
        PrintWriter writer = response.getWriter();
        writer.write(jsonObject.toString());
    }
 
    ...
}

As can be seen from the code above, Spring exploits MVC to it's full potential and provides the flexibility to tailor the view to exactly suit our needs.