Archive

Archive for the ‘Spring’ Category

JSR 303 Bean Validation Using Spring 3

March 10th, 2010 27 comments

The JSR 303 specification provides a metadata model for JavaBean validation. The validation API provides a variety of annotations that makes validation easy at any layer. In this post I will demo Spring 3’s support for JSR 303 in the web layer. You can download the code here (eclipse project).

The first part of the post talks about creating a simple bookstore admin application using Spring MVC. The second part of the post will add JSR 303 validation. If you are an experienced Spring developer, you can safely skip to the second part. The final part will show how to customize the validation error messages.

1. Online Bookstore Admin Application

The admin application will be designed to allow administrators enter information about new books. Here are the steps that implement this requirement:

Step 1. Create a web project and add all the required jars
I will be using Eclipse’s and here is a list of the required jars that need to be in the classpath:

org.springframework.asm-3.0.1.RELEASE.jar
org.springframework.beans-3.0.1.RELEASE.jar
org.springframework.context-3.0.1.RELEASE.jar
org.springframework.context.support-3.0.1.RELEASE.jar
org.springframework.core-3.0.1.RELEASE.jar
org.springframework.expression-3.0.1.RELEASE.jar
org.springframework.test-3.0.1.RELEASE.jar
org.springframework.web-3.0.1.RELEASE.jar
org.springframework.web.servlet-3.0.1.RELEASE.jar
commons-collections-3.1.jar
hibernate-validator-4.0.2.GA.jar
jcl-over-slf4j-1.5.10.jar
joda-time-1.6.jar
jstl-1.2.jar
log4j.jar
slf4j-api-1.5.8.jar
slf4j-log4j12.jar
validation-api-1.0.0.GA.jar

Step 2. Create a web-Context.xml file under WEB-INF folder to hold web layer spring bean configuration. Here are the contents of the file:

		
		<?xml version="1.0" encoding="UTF-8"?>
		<beans xmlns="http://www.springframework.org/schema/beans"
			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			xmlns:context="http://www.springframework.org/schema/context"
			xmlns:mvc="http://www.springframework.org/schema/mvc"
			xsi:schemaLocation="
				http://www.springframework.org/schema/beans	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
				http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
			
			<!-- Enable annotation driven controllers, validation etc... -->
			<mvc:annotation-driven />
			
			<!-- Controllers package -->
			<context:component-scan base-package="com.inflinx.blog.bookstore.web.controller" />
		
			<!-- JSP page location -->
			<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
				<property name="suffix" value=".jsp"/>
			</bean>
			 	
		</beans>
			
	

Step 3. Add Spring MVC Dispatcher Servlet to web.xml file. In the declaration below, Spring MVC will handle all URL requests to html pages.

		
		<?xml version="1.0" encoding="UTF-8"?>
		<web-app version="2.5" 
			xmlns="http://java.sun.com/xml/ns/javaee" 
			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
			xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
			http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
			  
		  <servlet>
				<servlet-name>bookstore</servlet-name>
				<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
				<init-param>
					<param-name>contextConfigLocation</param-name>
					<param-value>/WEB-INF/web-Context.xml</param-value>
				</init-param>
				<load-on-startup>1</load-on-startup>
			</servlet>
		
			<servlet-mapping>
				<servlet-name>bookstore</servlet-name>
				<url-pattern>*.html</url-pattern>
			</servlet-mapping>
		
		</web-app>
		
	

Step 4. Create a Book domain object to hold information about a book:

		package com.inflinx.blog.bookstore.domain;

		public class Book
		{
			private String name;
			private String description;

			public String getName()
			{
				return name;
			}
			public void setName(String name)
			{
				this.name = name;
			}
			public String getDescription()
			{
				return description;
			}
			public void setDescription(String description)
			{
				this.description = description;
			}

			@Override
			public String toString()
			{
				return "Name: " + name + ", Description: " + description ;
			}
		}	
	

Step 5. Create a BookFormController to prepare the form and process form submission

		package com.inflinx.blog.bookstore.web.controller;
		
		import java.util.Map;
		
		import org.springframework.stereotype.Controller;
		import org.springframework.web.bind.annotation.RequestMapping;
		import org.springframework.web.bind.annotation.RequestMethod;
		
		import com.inflinx.blog.bookstore.domain.Book;
		
		@Controller
		@RequestMapping("/book.html")
		public class BookFormController
		{
			// Display the form on the get request
			@RequestMapping(method=RequestMethod.GET)
			public String showForm(Map model)
			{
				Book book  = new Book();
				model.put("book", book);
				return "form";
			}
			
		}
	
	

Step 6. Create form.jsp page with a form to capture book details:

	
		<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
		<html>
			<head></head>
			<body>
				<form:form method="post" action="book.html" commandName="book">
					<table>
						<tr>
							<td>Name:</td> <td><form:input path="name" /></td>
						</tr> 
						<tr>
							<td>Description:</td> <td><form:textarea path="description"/></td>
						</tr>
						</table>
					<input type="submit" value="Create" />
				</form:form>
			</body>
		</html>
	
	
	

The form will be submitted to the book.html page.

Step 7. Modify BookFormController to read the submitted data and process it.

		
		// Process the form. 
		@RequestMapping(method=RequestMethod.POST)
		public String processForm(Book book, Map model)
		{
			// Persistence logic to save the book will go here

			// Add the saved book to the model
			model.put("book", book);
			return "result";
		}	
	

Step 8. Create a result.jsp page to display the form submission result:

		<html>
			<body>
				${book.name} is stored in the database
			</body>
		</html>
	

Deploy the application and go to http://<yourserver:port>/bookstore/book.html. The page should present a form shown below:

Form

Form

Enter the book name “Test Book” and submit the form. You should see a screen that looks similar to image below:

Form Submission Result

Form Submission Result

 

2 Adding JSR 303 validation

Consider the following validation requirements to the book class:
a. Name and Description cannot be null or blank
b. Description cannot be more than 50 characters

Here are the steps to add the above validation requirements:

Step 1. Add @NotEmpty and @Size annotations to the name and description files of the Book class

		public class Book
		{
			@NotEmpty
			private String name;
			
			@Size(min=1, max=50)
			private String description;
			
			// Getters and setters here	
		}
	

NotEmpty annotation is not part of JSR 303 specification. It is part of Hibernate Validator framework which is the reference implementation for JSR 303.

Step 2. Modify BookFormController to have Spring validate the submitted data. This is done by adding a @Valid annotation before the book method parameter. The result of the validation can be accessed using the BindingResult method parameter.

		// Process the form. 
		@RequestMapping(method=RequestMethod.POST)
		public String processForm(@Valid Book book, BindingResult result, Map model)
		{
			if(result.hasErrors())
			{
				return "form";
			}
			// Persistence logic to save the book will go here

			// Add the saved book to the model
			model.put("book", book);
			return "result";
		} 	
 	

Step 3. Modify the form.jsp so that error messages can be displayed:

 		<form:form method="post" action="book.html" commandName="book">
					<table>
						<tr>
							<td>Name:</td> <td><form:input path="name" /></td> <td><form:errors path="name" /></td>
						</tr> 
						<tr>
							<td>Description:</td> <td><form:textarea path="description"/></td> <td><form:errors path="description" /></td>
						</tr>
						</table>
					<input type="submit" value="Create" />
		</form:form>
 	

Redeploy the application and when you submit an empty form, you should see validation failure messages next to the fields:

Validation Failed

Validation Failed

 

3 Customizing error messages

The validation failure messages in the image above are default to the framework. To make custom error messages appear follow these steps:

Step 1. Create a messages.properties file under the WEB-INF folder. Add the following messages:

   		NotEmpty.book.name=Name is a required field
		Size.book.description=Description must be between 1 and 50 characters
   	

Each message above follows this convention:

<CONSTRAINT_NAME>.<COMMAND_NAME>.<FIELD_NAME>

Step 2. Let Spring know about the newly created properties file. This is done by modifying the web-Context.xml file to include this bean declaration:

   	
			
	
    

Redeploy the application and submit an empty form. This time you should see custom error messages appear next to the fields:

Custom Validation Failed Messages

Custom Validation Failed Messages

 

Download the source code for this post here. The application is tested on Glassfish 3.0 and WebLogic 10.3.

 

Theming Websites using Spring MVC

October 8th, 2009 8 comments

Many websites today allow their users to theme or change the look and feel of their sites. Gmail for example, currently provides over 34 themes to skin the mail interface. Themes can make websites more interactive and put the user in the driver seat when it comes to experiencing the site.

Conceptually, a theme is a collection of static resources such as stylesheets and images. When a user picks a theme, the theme’s styles and images dynamically gets associated with the site. In this post, I will create a simple Spring MVC Web application and show how Spring MVC can be used to manage theme resources easily. If you have used Spring MVC quite a bit, you can safely skip to Step 5.

Step 1: The first step in the process is to create a Spring MVC web project. Following maven conventions, here is the directory structure of the project:

Spring MVC Theme Project Structure

Spring MVC Theme Project Structure

Step 2: The next step is to add the required jars. Here is the dependency list that needs to be added to the pom.xml file:

		
		<dependencies>
			<dependency>
			    <groupId>org.springframework</groupId>
			    <artifactId>spring-webmvc</artifactId>
			    <version>2.5.6.SEC01</version>
			    <scope>compile</scope>
        		</dependency>	
        
			<dependency>
				<groupId>log4j</groupId>
				<artifactId>log4j</artifactId>
				<version>1.2.14</version>
				<scope>compile</scope>
			</dependency>
		</dependencies>			
	

This would add the following jars to the project:

Spring MVC Theme Jars

Spring MVC Theme Jars

Step 3: The next step is to add Spring “goodness” to the project. This is done by adding Spring MVC dispatcher servlet definition to web.xml:

		<!-- Spring MVC Servlet -->
		<servlet>
			<servlet-name>springthemes</servlet-name>
			<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
			<load-on-startup>1</load-on-startup>		
		</servlet>
			
		<servlet-mapping>
			<servlet-name>springthemes</servlet-name>
			<url-pattern>*.html</url-pattern>
		</servlet-mapping>	
	

The Spring MVC Dispatcher Servlet by default looks for the <context-name>-servlet.xml file for Web Tier bean definitions. Create a file called springthemes-servlet.xml under WEB-INF folder with the following information:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
		xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	
	<!-- Scan for controllers -->
	<context:component-scan base-package="com.inflinx.blog.springthemes.web.controller" />
	
	<!-- Views are jsp pages defined directly in the root -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:suffix=".jsp"/>
    
</beans>

Step 4: To keep things simple, create a controller class called HomeController that simply redirects to the home.jsp page. Here is the HomeController class definition:

	package com.inflinx.blog.springthemes.web.controller;

	import org.springframework.stereotype.Controller;
	import org.springframework.web.bind.annotation.RequestMapping;
	import org.springframework.web.bind.annotation.RequestMethod;

	@Controller
	@RequestMapping("/home.html")
	public class HomeController
	{
		@RequestMapping(method = RequestMethod.GET)
		public String showHome()
		{
			return "home";
		}
	}

Here is the home.jsp file:

<html>
	<head>
		<title>Welcome to Spring Themes</title>	
	</head>
	
	<body>
		Hello Visitor!!
	</body>
</html>

If you deploy the application and hit http://<server:port>/springthemes/home.html, you should see a page that looks like this:

Spring MVC Theme Default Page

Spring MVC Theme Default Page

Now that we are successfull in creating a simple Spring MVC project, lets add two themes to it – dark theme and bright theme. The site automatically gets the “dark” theme during nights and the “bright” theme during day time.

Step 5: In this step, lets create the css files (one of the many static resources that a theme can have) associated with each theme. Here are the css files (I placed them under the themes folder):

dark.css

	body {
		font-size:13px; 
		text-align:center;
		color: white;
		background-color: black
	}

bright.css

	body {
		font-size:9px; 
		text-align:center;
		color: blue;
		background-color: white;
}

Step 6: The next step is to define the themes. The default way to do this in Spring MVC is to use one property file for each theme. Here are the two theme definitions:

#dark theme properties file dark.properties
css=themes/dark.css
page.title=Welcome to Dark Theme
welcome.message=Hello Visitor!! Have a Good night!!

#bright theme properties file bright.properties
css=themes/bright.css
page.title=Welcome to Bright Theme
welcome.message=Hello Visitor!! Have a Good day!!

Step 7: Now that we have defined the themes, we need to tell Spring where to find them. This is done using a ThemeSource. Add the following line to the springthemes-servlet.xml file:

   

Step 8: Spring needs to know what theme to use when a request is made. This is done using a ThemeResolver. Spring provides three theme resolvers out of the box: FixedThemeResolver, SessionThemeResolver, CookieThemeResolver that are sufficient for most use cases. However, our site needs to inherit a theme based on the time, we will create a new theme resolver called DarkAndBrightThemeResolver:

package com.inflinx.blog.springthemes.web.resolver;

import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.theme.AbstractThemeResolver;

public class DarkAndBrightThemeResolver extends AbstractThemeResolver
{
	@Override
	public String resolveThemeName(HttpServletRequest arg0)
	{	
		return isNight() ? "dark" : "bright";
	}

	// Pretty lame implementation
	private boolean isNight()
	{
		return new Random().nextBoolean();
	}
	
	@Override
	public void setThemeName(HttpServletRequest arg0, HttpServletResponse arg1, String arg2)
	{	
	}
}		

Add the newly created theme resolver definition to the springthemes-servlet.xml file:

   

Step 9: The final step is use modify the view to use the theme. This is done using tag. Make the following changes to home.jsp page:

  <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
  <html> 
  	<head>
  		<link  rel="stylesheet" href='<spring:theme code="css"/>' type="text/css" />
  		<title><spring:theme code="page.title"/></title>	
  	</head>
  	<body>
  		<spring:theme code="welcome.message" />
  	</body>
  </html>

Now, redeploy the application and as you refresh the URL, you should randomly see the site switch between the two themes. Here is the site with the two themes:

Dark Theme

Dark Theme



Bright Theme

Bright Theme

Categories: Spring Tags: ,

Reading Operational Attributes using Spring LDAP

September 1st, 2009 2 comments

Ldap Servers maintain operational attributes (introduced in version 3) for administrative purposes. For example, the Tivoli Directory Server maintains the pwdAccountLockedTime operational attribute to record the time a user’s account got locked.

These operational attributes are unique in the sense that they are not part of an object class and are not returned unless they are explicitly requested by name. Here are two ways of reading operational attributes using Spring Ldap:

Using lookup:

LdapTemplate ldapTemplate = new LdapTemplate(context);
ldapTemplate.lookup("USER_DN", new String[]{"OPERATIONAL_ATTR"}, new ContextMapper(){
		@Override
		public Object mapFromContext(Object ctx)
		{
			DirContextAdapter context = (DirContextAdapter)ctx;
			return context.getStringAttributes("OPERATIONAL_ATTR");
		} }); 

Using Search:

LdapTemplate ldapTemplate = new LdapTemplate(context);
ldapTemplate.search("SEARCH_BASE", "uid=UNIQUE_USER_NAME", 1, new String[]{"OPERATIONAL_ATTR"}, new ContextMapper(){
		@Override
		public Object mapFromContext(Object ctx)
		{
			DirContextAdapter context = (DirContextAdapter)ctx;
			return context.getStringAttributes("OPERATIONAL_ATTR");
		} });
Categories: Ldap, Spring Tags:

Spring not able to retrieve Sybase database metadata

August 29th, 2009 2 comments

Recently, when trying to execute a Sybase stored procedure using SimpleJdbcCall, I found that the Spring framework could not read the database metadata. SimpleJdbcCall uses the metadata to intelligently figure out the parameters and their types and just makes stored procedure invocation painless.

After going through Spring’s source code, I found that Spring uses the database product name to determine how the metadata should be loaded. Turns out that the commonDatabaseName method in the JdbcUtils that is used to get the product name does a string comparison against “sql server” and our Sybase server is named “SQL Server”.

I submitted a patch to do this comparison with out taking considering the case. Hopefully this gets considered in the 3.0 release.

Categories: Spring Tags:

Spring Ehcache Integration

February 26th, 2009 20 comments

In this post I will share how to cache method results using Ehcache and Spring AOP. This is based on the post

The first step is to add all the required jars to the project. At minimum, the following jars should be present:

Spring and related jars (using 2.5.6 version here):

  • spring-2.5.6.jar
  • commons-logging.jar
  • commons-collections.jar
  • aspectjrt.jar
  • aspectjweaver.jar
  • jsr250-api-1.0.jar

Ehcache and its dependencies (using version 1.5.0):

  • ehcache-1.5.0.jar
  • backport-util-concurrent-3.0.jar
  • jsr107cache-1.0.jar

For the sake of this post, I will be using a DemoService with a method whose results need to be cached.

package com.inflinx.blog.service;
import java.util.List;
public interface DemoService
{
	public List getCarTypes(String filter);
}

Here is a dummy implementation of the above service:

package com.inflinx.blog.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;

@Service("demoService")
public class DemoServiceImpl implements DemoService
{

	public List getCarTypes(String filter)
	{
		List carTypes = new ArrayList();
		carTypes.add("Mini");
		carTypes.add("Economy");
		carTypes.add("Sport Utility");
		carTypes.add("Convertible");
		carTypes.add("Standard");
		
		return carTypes;
	}
}

And the application context with bean scanning turned on:




       
       
	   	       
  

The next step in the process is to add ehcache.xml to the classpath. Details on this configuration file can be found at Ehcache web site



	
     
	
	

    

Spring makes integration with Ehcache easy with EhCacheManagerFactoryBean and EhCacheFactoryBean classes. The EhCacheManagerFactoryBean provides access to Ehcache’s CacheManager and the EhCacheFactoryBean exposes caches defined in ehcache.xml.

To make use of these beans, lets add the following to the application context file:




The next step is to create an AOP Aspect that would provide caching transparently:

package com.inflinx.blog.aspect;

import javax.annotation.Resource;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component("cacheAspect")
@Aspect
@Order(2)
public class CacheAspect
{
	@Resource(name="carTypesCache")
	private Cache cache;
	
	@Around("execution(* com.inflinx.blog.service.DemoService.getCarTypes(java.lang.String))")
	public Object cacheCarTypes(ProceedingJoinPoint joinPoint) throws Throwable
	{
		Object[] arguments = joinPoint.getArgs();
		String location = (String)arguments[0];
		Element element = cache.get(location);
		if(null == element)
		{
			Object result = joinPoint.proceed();
			if(null != result)
			{
				element = new Element(location, result);
				cache.put(element);
			}
		}
		return element != null ? element.getValue() : null;
	}
}

Finally, declare the newly created aspect in the application context file:




Spring Modules provides a great alternative for declarative caching with @Cacheable annotation. As of this post, Spring Modules is still in “draft” status.

You can download the source code used in this post here

Categories: Spring Tags: ,

Integrating Quartz with Spring

September 24th, 2008 10 comments

Spring’s reference documentation goes over in detail on integrating Quartz with Spring. However, the technique requires extending Spring’s QuartzJobBean class. Here are steps for achieving the same integration with out dependencies on QuartzJobBean class:

Step 1: Create the Quartz job that needs to be scheduled. Here is a simple Hello world job class:

public class HelloWorldJob implements Job
{
  public void execute(JobExecutionContext jobExecutionContextthrows JobExecutionException
  {
    System.out.println("Hello World");
  }
}
Notice that we are simply implementing org.quartz.Job interface.

Step 2: In the Spring’s context file, define a JobDetail bean for this job. A JobDetail contains metadata for the job such as the group a job would belong to etc.

<?xml version=”1.0″ encoding=”UTF-8″?>
 <beans xmlns=”http://www.springframework.org/schema/beans” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance
   xmlns:p=”http://www.springframework.org/schema/p” xmlns:context=”http://www.springframework.org/schema/context
   xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd“>
 
 <bean id=”helloWorldJobDetail” class=”org.quartz.JobDetail”>
      <property name=”name” value=”helloWorldJobDetail” />
      <property name=”jobClass” value=”local.quartz.job.HelloWorldJob” />
 </bean>

Step 3: Again, in the context file, define a Trigger that would trigger the job execution. For simplicity sake, lets use a SimpleTrigger. More about triggers can be found in the Quartz documentation:

 <bean id=”simpleTrigger” class=”org.quartz.SimpleTrigger”>
     <property name=”name” value=”simpleTrigger” />
     <property name=”jobName” value=”helloWorldJobDetail” />
     <property name=”startTime”>
       <bean class=”java.util.Date” />   
     </property>
  </bean>

The startTime property is set to “now” which means that the job will run as soon as the spring completes bean loading.

Step 4: Finally, define a SchedulerFactoryBean that sets up the Quartz scheduler:

<bean class=”org.springframework.scheduling.quartz.SchedulerFactoryBean”>
     <property name=”jobDetails”>
        <list> <ref bean=”helloWorldJobDetail” /> </list>
     </property>
     <property name=”triggers”>
        <list> <ref bean=”simpleTrigger” /> </list>
     </property>
 </bean>

Notice that this is the only Spring class used in the configuration. When the application loads the Spring context, the job should run and print “Hello World”

In most cases, the job instances rely on external services to perform their job (such as an email service to send out email). These external components can be easily made available to the job instances via dependency injection. Let’s modify the above class to display a custom message:

 public class HelloWorldJob implements Job
{
  private String message;
  
  public void setMessage(String message)
  {
    this.message = message;
  }
  
  public void execute(JobExecutionContext jobExecutionContextthrows JobExecutionException
  {
    System.out.println(message);
  }
}

Next, in the Spring context file, add a bean that contains the custom message we want to display:

<bean id=”message” class=”java.lang.String”>
  <constructor-arg value=”Hello Again!!” />
 </bean>

With Quartz 1.5 and above, dependency Injection into Quartz jobs can be done via a JobFactory instance. Here are the modifications that need to be done to the Spring context:

<bean id=”jobFactory” class=”org.springframework.scheduling.quartz.SpringBeanJobFactory” />
 
 <bean class=”org.springframework.scheduling.quartz.SchedulerFactoryBean”>
      <property name=”jobFactory” ref=”jobFactory” />
      <property name=”schedulerContextAsMap”>
          <map> <entry key=”message” value-ref=”message” /> </map>   
      </property>
      <property name=”jobDetails”>
         <list> <ref bean=”helloWorldJobDetail” /> </list>
      </property>
      <property name=”triggers”>
        <list> <ref bean=”simpleTrigger” /> </list>
       </property>
  </bean>

Now when the Spring context gets loaded, the job should run and print “Hello Again!!”.

Categories: Quartz, Spring Tags: ,

Spring MDP

July 1st, 2008 No comments

MDP (Message Driven Pojo) introduced in Spring 2.x offers a nice alternative to EJB’s Message Driven Beans.

package com.inflinx.test.mdp;

import javax.jms.Message;
import javax.jms.MessageListener;

public class TestMdp implements MessageListener
{
  public void onMessage(Message message)
  {
    System.out.println(message);
  }
}

Creating and configuring a MDP in Spring is a pretty straight forward process. The first step is to create a class that implements javax.jms.MessageListener interface.

Once the message listener is in place, the next step is to configure the MDP and related JMS components in Spring application context.  
<bean id=“testMdp” class=com.inflinx.test.mdp.TestMdp” />
<jee:jndi-lookup id=“connectionFactory” jndi-name=“jms.testConnectionFactory” />
<jee:jndi-lookup id=“queue” jndi-name=“jms.testQueue” />
<bean id=“jmsTransactionManager” class=“org.springframework.jms.connection.JmsTransactionManager”>
<property name=“connectionFactory” ref=“connectionFactory” />


</bean>



<bean id=“jmsContainer” class=“org.springframework.jms.listener.DefaultMessageListenerContainer”>

<property name=“connectionFactory” ref=“connectionFactory”/>

<property name=“destination” ref=“queue”/>

<property name=“messageListener” ref=“testMdp” />

<property name=“transactionManager” ref=“jmsTransactionManager” />

</bean>

Categories: Solutions Log, Spring Tags: