Monday, December 15, 2008

Using Log4J in Spring: Effective Logging

Spring supports logging in its usual plug and use format. To use Apache's log4j in a Spring-Maven environments:

  1. Add the log4j dependency to the pom
  2. In web.xml of the application define spring listener for log4j and its config location
  3. In the config location put in the appropriate properties file defining your loggers



The log4j.properties at the above link is fully commented to help you(and me) understand how to use a properties file to split your logs at a finer level.

I have realized that in order to utilize the full power of log4j it is important to understand and use log4j.properties. This can help you to isolate logs from different part of of your application- something that can be really handy when you are trying to pin-point the source of trouble in a large system. The bigger and more distributed your system becomes, more important and useful logging appears.
As usual, I have focussed only on the practical aspects. For knowing more about log4j, see:





Tuesday, December 9, 2008

PostgreSQL Vs MySQL

My team decided to use PostgreSQL instead of MySQL. This got me interested in finding out why. Found these articles that helped me understand:

(a recent comparison, subtly votes in favor of PostgreSQL)
(this is the most concise comparison but is a little old, very nicely tabulated)
(a very old comparison to give some prespective)

In a nutshell, both are equally good in the current scenario; though before the 8th release of PostgreSQL,  MySQL held a distinct advantage. Currently PostgreSQL offers a wider range of features and on the whole MySQL is a bit faster. However with every release MySQL is inching towards more features and PostGreSQL towards more speed. MySQL is currently more widespread, perhaps because it is older and is preferred by the widespread PHP community. Another difference is the licensing. Both are open-source but MySQL is under GNU while PostgreSQL is under BSD.  

Monday, December 8, 2008

Using JAXB in a Spring-Maven Environment for WebServices

In a Spring application you can consume a webservice using JaxRpcPortProxyFactorybean or XFireClientFactoryBean (in conjunction with XFire). However, there is another way which can prove to be extremely useful and convenient if you are using Spring and Maven: by using Spring and Maven in conjunction with JAXB. As usual, I will focus on using JAXB and not about JAXB. To learn more about JAXB see:


In this article we will cover
1. Setting up JAXB in Spring environment to generate stubs for the webservice
2. Using it in an external project or the same project.

As per the default maven build structure, you need to make a package called "wsdl" under src/main and place a copy of wsdl of the webservice you wish to use. Then configure your pom file with the right dependencies:



Two things that you should notice in the pom besides JAXB dependencies are the build plugins maven-source-plugin and maven-jaxb2-plugin. They will generate stubs for your webservice in the "target" directory under "generated-sources" when you compile the project/ generate resources using maven. After that your webservice should be ready to used. Almost :D.

The generated source will contain stubs that correspond to exposed functions, responses and the various objects used. The name of the stubs will correspond to name in wsdl. In the same project you can use it by importing stubs from the package specified in com.saveenkumar.myApp.someWebService.types For an external project, you just need to import the project as a dependency.

Let us now see how to use these stubs. You will be able to use the webservice in your Spring app with the help of org.springframework.ws.client.core.WebServiceTemplate. You can see the bean config that you can use to inject it here:


Note that the "contextPaths" property of the JAXB marshaller is same as the  property above. If you want to dig still deeper, have a look about using WebServiceTemplate  at:


and



It may be a good idea to hide the WebServiceTemplate behind a nice interface to abstract away the user from the generated JAXB classes.

The generated classes will always have a class called "ObjectFactory". There will also be objects corresponding to every operation, every response and every object used in these transactions. Let us say our webservice exposes the following operations:

List getAllStockInfo();
List getStocksByVolatilityRange(float low, float high);
StockInfo getStockInfo(String ticker);

May generate following objects:

ObjectFactory
ArrayOfStockInfo
StockInfo
GetAllStockInfo
GetAllStockInfoResponse
GetStockInfo
GetStockInfoResponse
GetStocksByVolatilityRange
GetStocksByVolatilityRangeResponse

Let us say we want to use GetStockInfo. The code would look something like:



I would also recommend using SoapUI to test your webservices. 

Tuesday, December 2, 2008

@Resource and @Autowired

In September I wrote an article on using @Autowired for testing RMI services in Spring. Recently when trying to test a webservice consumer, I ran into trouble with @Autowired. Instead using @Resource (javax.annotation.Resource in Java 1.6) seemed to work fine. Digging I found this article in Spring forum:


which pointed to this in spring reference:

Seems the two are pretty similar. Using 
@Qualifier (org.springframework.beans.factory.annotation.Qualifier) with @Autowired solved the problem and in the end I could use either. 

Monday, November 24, 2008

Serialization

Serialization is not just about implementing the java.io.Serializable interface, I learned. Thanks to this article pointed by my colleague, Ben. Hope it helps you too.

Retreiving Stored Objects Using Hibernate

This one is relatively simple. 
  1. Use org.springframework.orm.hibernate3.support.HibernateDaoSupport to manage data (add or retrieve)
  2. Refer to the official hibernate documentation to see how you can use Criteria to narrow your result set by clicking here
  3. use getSession() from HibernateDaoSupport to get the hibernate session and fire away using what you learned in step 2

Thursday, October 30, 2008

Persisting A List of Custom Objects Using Hibernate in a Spring Env.

The prospect of persisting an object using hibernate into a database and then reading it back did not seem challenging with good old hibernate taking care of most things. 

Piece of cake? Not quite actually as I discovered while trying to do it for a List of custom objects. Let us see what were the challenges and how I found the solutions. Let us assume I wish to persist an object that contains the current situation of all stocks trading in the market. Our simplistic object has an id and a list of stocks: 


The list of stocks is made of a custom object:


And since we refuse to live without spring, we need some bean config:


With spring so near how can we forget maven and the pom dependencies:


Phew! Sometimes I forget how much these XML config make our lives easier (?).  Now, had it been my own custom object, I would have used @Embedded. But what do I do with a java collection. I was tempted to mark it with @Lob and it compiled fine. But when I actually tried to persist it, it gave me one big, fat ClassCastException: java.util.ArrayList cannot be cast to java.sql.Blob. OK, so objects don't turn into byte arrays overnight and that attempt was dumb and desperate. 

Then what? Referring "Java Persistence with Hibernate" (Bauer and King,2006) and official hibernate docs helped my to make my classes look like this:



Now this works like a charm: at least the part about starting your app, seeing your tables created perfectly and storing your objects at the right place with some class like:


In our next post we will see how we read this information back and use it if I face any difficulty with it as well!

Wednesday, October 8, 2008

ActiveMQ Message Consumer in Spring

In the last blog we saw how to configure an ActiveMQ broker to run in a Spring environment. In this blog we will see how to configure a message consumer. Again, I am not trying to explain how consumers work but just sharing code and config to make it work in Spring :p

Since we have the luxury of Spring , we will use a message listener container provided by the framework: SimpleMessageListenerContainer (org.springframework.jms.listener.SimpleMessageListenerContainer ). My needs were simple and non-transactional so this container suffices

The basic reason is the desire to be message driven i.e. I want my app to take some actions as and when it receives messages. The container bean definition should look like:

    <bean id="jmsContainer" class="org.springframework.jms.listener.SimpleMessageListenerContainer">
        <property name="autoStartup" value="true"/>
        <property name="connectionFactory" ref="myConnectionFactory"/>
        <property name="destination" ref="myDestination"/>
        <property name="messageListener" ref="myMessageListener"/>
        <property name="acceptMessagesWhileStopping" value="true"/>
    </bean>

This config makes the container start when the bean gets loaded and makes sure no messages are lost even if it is down. Further we need to specify the connection factory to use to connect to broker, the destination at broker from which we wish to hear and the message listener that ultimately handles the message. The config for these three will look like:

 <bean id="myDestination" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg value="myPackage.myQueue"/>
    </bean>

 <bean id="myConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:61636"/>
   </bean>

<bean id="myMessageListener" class="myPackage.MyMessageListener">       
    <property name="appName" value="My Application"/>
</bean>


Destination takes the name for destination in order to identify it at broker. the producer would refer it by the same name. JNDI can be used for more sophisticated look-ups which we may see some other time. Connection factory just needs url for a running broker. Message Listener is just our custom bean to handle messages. MyMessageListener would look like:

package myPackage;

import javax.jms.*;

public class MyMessageListener implements MessageListener {
    private String appName;

    public void setAppName(String appName){
        this.appName = appName;    
    }

    public void onMessage(Message message) {
        //do your stuff
    }
}

Finally, don't forget the POM dependencies included in last blog if you are using Maven. You should be good to go.

Tuesday, October 7, 2008

Running ActiveMQ Broker in Spring

ActiveMQ can run as an independent JMS server. This may be desirable if we want to run it independently of our spring application. However it is also possible that we may want to deploy a message broker within a spring environment. This may be simply because we need to do some unit testing or because our webapp is too small to break across several machines. Whatever be the reason. Let us make a note of basic steps to do it:

1. Put in your activemq.xml under the WEB-INF folder. Your ActiveMQ distribution(5.1.0 at time of this article) has this config file under the "conf" folder. We will not discuss configuring it here. Go here to read about configuring

2. The lib folder of the distribution has all possible jars that JMS may ever need in its lifetime. If you are not using Maven, you may need to copy the jars to your classpath. If you are using Maven, these dependencies should generally suffice for basic use.

        <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>2.5.5</version>
</dependency>

<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.3.1.4</version>
</dependency>

<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.1.0</version>
</dependency>

<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-web</artifactId>
<version>5.1.0</version>
</dependency>

Go here if you wish to simply run ActiveMQ using Maven
3. Put this bean definition in your spring conf:
<bean id="broker" class="org.apache.activemq.xbean.BrokerFactoryBean">
<property name="config" value="/WEB-INF/activemq.xml"/>
<property name="start" value="true"/>
</bean>
You should be good to go. Bringing up your Spring application will start the broker at tcp://localhost:61636

Friday, October 3, 2008

Understanding JMS with a Spring Perspective

Making some notes from the official JMS tutorial.

Why Messaging?
Messaging enables distributed communication that is loosely coupled. Messaging is used for communication between software applications or software components.

What is NOT Messaging?
Messaging is different from RMI, RPC or email

What is JMS?
The Java Message Service is a Java API to help you with your messaging needs

When to use JMS/ Messaging?
Use JMS if
  • you do not want to depend on any information about other components’ interfaces( so they are easily replaceable)
  • you want your app to run whether or not all components are up and running simultaneously
  • you want an app design that allows a component to send information to another and to continue to operate without receiving an immediate response
  • you want a guaranteed delivery, not necessarily immediately

What is the support for JMS in J2EE?
  • Message driven beans support JMS
  • JMS messages can participate in distributed transactions

Where can I get an open-source implementation for JMS API?
ActiveMQ from Apache is a great open source implementation. You can see others at java-source.net


What is a Messaging Domain?
Messaging domain denotes the style of messaging. There are basically two types of messaging domains: Point-to-Point(PTP) and Publish/Subscribe(pub/sub)

How is PTP different for pub/sub?
PTP style of messaging has following features:
• Each message has only one consumer.
• A sender and a receiver of a message have no timing dependencies. The receiver can fetch the message whether or not it was running when the client sent the message.
• The receiver acknowledges the successful processing of a message.

Use PTP messaging when every message you send must be processed successfully
by one consumer.

pub/sub is characterized by:
• Each message may have multiple consumers
• Publishers and subscribers have a timing dependency. A client that subscribes to a topic can consume only messages published after the client has created a subscription, and the subscriber must continue to be active in order for it to consume messages.

Use pub/sub messaging when each message can be processed by zero, one, or many consumers.

What does JMS support out of these two?

JMS supports both. In fact it even provides something called durable subscriptions which allow you to combine flexibility and reliability of queues of PTP with the ability to allow clients to send messages to many recipients of pub/sub

Using JMS will the messages be consumed asynchronously or synchronously?
JMS supports both. However the biggest advantages of JMS arise out of asynchronous communication

What are the main parts of a JMS application?
  • Administred Objects (connection factories, destinations)
  • Connections
  • Sessions
  • Message producers
  • Message consumers
  • Messages
A connection factory is used to create a connection. A connection is used to create a session. A session can create a producer, consumer or a message. Producer send messages to a destination while consumers receive messages from the destination.

Does Spring support JMS?
Absolutely. You can read it here. If you are using ActiveMQ, you may want to see this too.

Why should I use spring to manage interactions with JMS?
For pretty much the same reason you would use spring to manage your database, cache etc. etc. : it makes your life easier. Seriously. Helps you cut down the "boiler-plate" code and gives you more specific exceptions besides the regular dependency injection benefits.

Wednesday, October 1, 2008

Setting up Quartz in a Spring-MySQL Environment

If you are using a persistent JobStore in Quartz, you will have to back your spring application with a DB. MySQL can be pretty convenient for local unit testing. Besides the regular spring DataSource config, you need a few more things here and there. I did not find any comprehensive "todo" checklist for MySQL online. So summing up what worked for me.

Using SchedularFactoryBean you can specify a MySQL DataSource and fine-tune it using quartz properties. You can see this in a config file I had published earlier:

XML Config

Besides this, you need to have the following dependencies for sure in your pom if you are using Maven:

POM dependencies

If you are not using maven, the corresponding jars should be in the classpath.

Finally, don't forget to run the SQL script to create tables in your database provided by quartz:

Creating DB Tables for Quartz

Wednesday, September 24, 2008

The Mysterious Ways of SchedulerFactoryBean

Using Spring framework and Quartz, I wanted to make some dynamic Jobs and triggers. After banging my head and some accidents I finally understood how to use it. The API docs say:

"For dynamic registration of jobs at runtime, use a bean reference to this SchedulerFactoryBean to get direct access to the Quartz Scheduler (org.quartz.Scheduler). This allows you to create new jobs and triggers, and also to control and monitor the entire Scheduler."

What the hell that means, I couldn't figure. Hunting for some examples on the web didn't help either. In one of my posts I have given a link to fine tune SchedulerFactoryBean for static jobs. Picking from there, let us assume you have a Stocks Alert Manager to which you wish to give a spring managed scheduler using your very own SchedulerFactoryBean . Let us assume your stockAlertsManager looks like this:


Then your bean config should look something like this:

If you have not noticed, the scheduler property of StockAlertsManager is of type org.quartz.impl.StdScheduler but in the bean config I have set it to the reference of our all-powerful SchedulerFactoryBean. Despite of the mismatch in types your spring application will not complain and initialize the scheduler property nicely. Even when SchedulerFactoryBean does not in any way extend StdScheduler or implement Scheduler . Wierd, counter-intuitive but works. Re-visiting the API doc:

"For dynamic registration of jobs at runtime, use a bean reference to this SchedulerFactoryBean to get direct access to the Quartz Scheduler (org.quartz.Scheduler). This allows you to create new jobs and triggers, and also to control and monitor the entire Scheduler."

Well, they literally meant it! Who would have thought?!

Tuesday, September 23, 2008

Using Autowiring for Testing RMI Services in Spring

Scehduling can be a common requirement in many applications. However testing such an application that used RMI with JUnit and JMock in a Spring-Maven environment turned out to be a little tricky for me. Thanks to the help of a colleague (thanks Mudassir!) and some head banging, I was able to find a way: Autowiring.

Generally my basic JUnit test cases have the following features:
1. The whole class annotated by @RunWith(JMock.class) - org.junit.runner.RunWith;
2. A set up method (the init method) annotated with @Before - org.junit.Before
3. The test cases annotated @Test - org.junit.Test
4. JUnit4Mockery used to mock relevant interfaces - org.jmock.integration.junit4.JUnit4Mockery
5. The usual expectatons and assertions
6. Spring adds punch with ability to mock request, response, sessions - org.springframework.mock.web.*

A Simple Test Case

Works fine for most things. Now picture this: you are developing application that needs to check stock prices every five minutes and send alerts to registered users if need be. Lets say there are three modules being developed for it: the user interface using which a user may register for an alert for stock price, the scheduler that keeps track of these alerts and the workflow engine that takes care of the alerts once fired. A classic MVC approach so far.

The controller accepts alerts from user interface and schedules Jobs that forward all information to the workflow. Let us assume these three modules are being developed by three different teams sitting in three corners of the world (ok, may be three corners of the office or just three different/independent machines/servers).

Now, when you are making the controller, you are essentially dependent on view for input and on the model for feedback (if any) for your input. We can provide access to our controller using any RMI strategy. For our example, we consider Spring's HttpInvoker. We intend to write a a test case to test the controller module.

Our controller has a remote service running in a spring environment. If it had been a simple servlet listening to ordinary post/get requests, writing a test case with MockHttpRequest would be a piece of cake. However when it is an RMI service, what mock up to use? An answer can be a test class looking something like this:

A Test Case For RMI Service


The answer lies in using SpringJUnit4ClassRunner and then auto-wiring the HttpInvokerService. ContextConfiguration points to the locations for the config xml. In the current case you should put it in "myPackage. If you are using Maven, the resources folder would be the right place to put it. The config file may look like:

Autowiring Config


If you are using Maven, don't forget to add the following dependencies:

Maven Dependencies

A few tweaks may be needed to suit your case but this should give you a general idea about using autowiring for your test cases in JUnit, JMock, Spring, Maven environment.

Friday, September 12, 2008

Maven Blues

Was facing a strange problem where Maven (version 2) would say something like "generics are not supported in -source 1.3" for Java 5 features. Adding the following the Plugins element in the pom helped:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugins>

Wednesday, September 3, 2008

Quartz and Spring

For scheduling purposes one can use Quartz with Spring. The basic usage can be learnt by going through the quartz tutorial and spring documentation on scheduling .

However when it came to using advanced usage like configuring job stores, I had a little difficulty finding stuff. A particular entry in the spring forum was really useful. These three resources were able to take care of my reasonably complex needs for scheduling. Hope they are of some use to you too.

Thursday, August 28, 2008

Splitting a Project into Modules in Maven

The beauty of Maven and Idea is the ease with which they allow you to manage, build and test your applications. Let us suppose we have a project that we wish to build in modules. For sake of simplicity we assume that the project has two basic modules: a webapp module and a core module.

Make a folder on the system for your project. In the folder make two folders by name "core" and "webapp". Also put a pom.xml which should look like:

parent pom

Notable things are the modules node and that the packaging is pom.

In the "core" folder make a folder "src" and put a pom.xml something like:

core pom

Main things to note about the pom is that packaging is "jar". ID are same as those in the parent pom. In "src" folder make two folders "main" and "test". Put a folder named "java" in each of them.

In the "webapp" folder create same directory structure as "core". The pom.xml here would look like:

webapp pom

Make the directory structure webapp -> src -> main -> webapp -> WEB-INF
in WEB-INF put in a web.xml file

You are good to go now. Now all you need to do is mvn idea:idea or mvn eclipse:eclipse (depending on what you are using) while being in the main folder to create the project with its modules.

Wednesday, August 6, 2008

Alternative to Using Valang Custom Functions


Valang provides a rich set of validation tools and is pretty simple. However in some cases you want more. The most obvious case that we encounter is validating if a date is in future or past wrt the current time on server. I know we can parse and input date to a date object readily using initBinder function of a SimpleFormController. But to compare it with the current date using pure varlang is something I could not find.

Luckily valang has an ability to use custom function. However I found it cumbersome to make one separate class for each function I may need. It would make more sense to allow users to group functions in one class to build a custom library of functions. Not to mention I could not find a proper working example of a custom function. So till I get my hands on one and this implementation improves, I have a simple work around.

Step 1: Define valang validations in the config file


<bean id="webMessageFormValidator"
class="myPackage.validators.FormBeanValidator">
<property name="valang">
<value>
<![CDATA[
{to:? IS NOT BLANK:'Please enter email addresses
for recepients.'}
{subject:? IS NOT BLANK:'Mail can not be blank.'}
{from:(length(?)> 0):'Please specify at least one
address.'}
]]>
</value>
</property>
</bean>


Step 2: Define the validator as follows


package mypackage.validators;

import org.springframework.validation.Errors;
import org.springmodules.validation.valang.ValangValidator;
import mypackage.FormBean;


public class FormBeanValidator extends ValangValidator {

public void validate(Object object, Errors errors) {

FormBean form = (FormBean) object;

//perform all validations and raise error flag
//if you find an error
if(isFutureTime(form.myDate()){
errors.rejectValue("myDate", "error.futureDate"
,"Time cannot be in the future.");
}

//dont forget call to super so as the validations
//defined in XML take place
super.validate(object, errors);
}


private boolean isFutureTime(Date formDate,
int hours, int minutes){
//check if time is in future
return false;
}

Tuesday, July 22, 2008

Problem Statement and Source Files


Theory without examples can be hard to grasp and less useful. So just making a small problem and corresponding files. Lets see
Problem statement: Given an online reporting application. There is a form that posts certain parameters and displays reports accordingly. Let us say that there are two basic parameters: report type and date range. Report type may be word, pdf, text. Date range consists of a from and a to time. Further user has an option to specify current time as the to time. Our form bean would look something like this:

package myPackage;

public class MyFormBean{
private String reportType;
//date in format dd/MM/yyyy HH:mm
privateDate fromDate;
private Date toDate;
private boolean useCurrentTime=true;

//.......
//public getters and setters for fields
//.......
}

Reports are denoted by a simple interface:
package myPackage;

public interface Report{
String getFileUrl();
String getType();
Date getCreationTime();
}
Reports are fetched using this interface:
package myPackage;

public interface DataBaseUtil{
List<Report> getReports(MyFormBean myFormBean);
}
which may have some implementation like:
package myPackage;

public class DataBaseUtilImpl{
private static DataBaseUtilImpl singleInst = new DataBaseUtilImpl();
private DataBaseUtilImpl(){}

public static DataBaseUtilImpl getInstance(){ return singleInst ; }

public List<Report> getReports(MyFormBean myFormBean){
//process command object to get a list of reports
}
}
The controller will be injected something like this in the config file:


 <bean id="reportFormController" class="myPackage.ReportFormController">
<property name "dataBaseUtil" ref="DataBaseUtilBean"/>
<property name="formView" value="reportInput"/>
<property name="bindOnNewForm" value="true"/>
<property name="successView" value="reportOutput"/>
<property name="validator" ref="myValidator"/>
<property name="commandName" value="reportFormBean"/>
<property name="commandClass" value="myPackage.MyFormBean"/>
</bean>
The actual form controller will look something like:

package myPackage;

import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.text.*;

public class ReportFormController extends SimpleFormController {
private DataBaseUtil dataBaseUtil;

public void setDataBaseUtil(DataBaseUtil dbUtil){
this.dataBaseUtil = dbUtil;
}

public DataBaseUtil getDataBaseUtil(){
return this.dataBaseUtil;
}

/*Override so as string inputs in the form bind directly to date in command object*/
@Override
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder dataBinder) throws Exception{
DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm");
df.setLenient(false);
dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(df,false));
super.initBinder(request,dataBinder);
}


@Override
protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response,Object command, BindException bindException)throws Exception{
//handle submit request
ReportFormBean repFormBean = (ReportFormBean ) command;

List<Report> reps ;

if(dataBaseUtil != null)
reps = dataBaseUtil.getReports(repFormBean);
else
reps = new ArrayList<Report>();

ModelAndView mv = showForm(request, response, bindException);

mvmodel.put("REPORTS", reps);

return mv;
}
}
From next post we will start exploring some practical problems using these files as our base.

Monday, July 14, 2008

Testing a SimpleFormController

Testing a SimpleFormController using JUnit and JMock was a small challenge I came across. After hitting a number of hurdles I managed to write tests that were meaningful and worked. Following points noted for people on similar quest :):

  1. Keep handy JMock Cheat Sheet , especially the Methods and Expectations part
  2. Use MockHttpServletResponse, MockHttpServletRequest and MockHttpSession in the package org.springframework.mock.web to mock web response, request and session respectively.
  3. Remember you can construct post requests and get requests with your MockHttpServletRequest using: MockHttpServletRequest mockRequest = new MockHttpServletRequest("POST","myUrl"); and MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET","myUrl");
  4. Finally use ModelAndView modelAndView = myController.handleRequest(mockRequest, mockResponse);
  5. Use JUnit asserts to verify ModelAndView as per your expectations

Generally your controller will follow this path: receive request-process-return ModelAndView to render. Processing may involve using the command object and passing values to the backend for processing. In your controller tests do NOT attempt to check backend- just mock it. Focus on checking the controller. A combination of expectations and asserts is your best bet to do the testing thoroughly. Let us explore a small example based on these principles in our next post.

Thursday, July 3, 2008

Conditional Form Binding

Form binding is a useful feature in Spring. However I needed to turn on or off form binding depending on certain conditions. Golden question, how to do it...

1. In the controller constructor (or in XML config for DI) call setBindOnNewForm(true);
2. Do NOT call/set setSessionForm(true);
3. Override suppressBinding and return true or false according to your condition. true will suppress form binding.

@Override
protected boolean suppressBinding(HttpServletRequest request){
boolean myCondition = false;
//some checks on myCondition depending on request params
return myCondition ;
}

Tuesday, July 1, 2008

Date Binding on SimpleFormController using initBinder

If you wish to bind an input date field in your web form directly to a Date property in your command object, you will need to override the initBinder method of the SimpleFormController. Following maps a date in dd/MM/yyyy format on the front-end to backend and vice-versa.

@Override
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder dataBinder) throws Exception{
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
df.setLenient(false);
dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(df,false));
super.initBinder(request,dataBinder);
}

Your valang validators can help you put some crisp checks on date if need be. Remember dd/mm/yyyy and dd/MM/yyyy are NOT same.

Thursday, June 26, 2008

SimpleFormController and Validation

While making your spring application you may come across the need to use a SimpleFormController. If so, there may be questions and confusions. The spring javadoc has some good documentation. Try this cheat sheet too if you are short on time or wish to revise your SimpleFormController knowledge:

SimpleFormController Cheat Sheet

After you get the controller running, you may want to validate your form. Besides using Validator class in the spring framework you may want to explore some configurable validation options. Check springmodules validation:

Spring Modules Validation

This gives you pointers on using Jakarta Commons and valang. I found valang much-much better than using either commons or the spring Validator class for server side validations. For client side validation I still need to make this thing work correctly as my jsp code generates the form on fly using tags. And tags and valang client side thingy dont gel well together. Will post a solution if I find one :).

And remember that expressions given for valang bean are like assertions. So the following check to make sure that a particular field should NOT be null is WRONG

{ myParam : myParam IS NULL : 'This param should not be null.' }

This, in effect says that your param SHOULD be null. So, the correct rule will be:

{ myParam : myParam IS NOT NULL : 'This param should not be null.' }

Your expressions should evaluate to true in order to avoid error. Remember that and you will be happy. Valang allows pretty complex and rigorous test conditions not possible with jakarata commons. Not easily. It is simpler, sweeter and downright good.

Saturday, February 9, 2008

The Beginning

There are a million people writing on Java. Why write more? Mainly to chronicle my learnings for personal and public use.

Java is vast. And when I say Java, I include J2EE, designing applications using Java and following things related to it. So where to begin? I will be mainly writing on multi-threading, spring, hibernate, junit, jmock and design patterns. It is not really meant to be a tutorial (not yet). Just sharing my learning and chronicling the same over time.

I will begin with spring.

The best place to start learning is the spring website at: http://www.springframework.org/documentation . I absolutely adore this light-weight, non-intrusive, well-designed framework. The reasons I will leave you to discover for converting you to a spring believer is not my intention. The framework consists of several modules which can be used independently. Again, I am not listing them but will mention as I write about them. This should not affect any article as various spring modules can be used independently.

I also refer Spring in Action by Craig Wells with Ryan Breidenbach. Lets see where we end up!