Tag Archives: spring

Spring Basic Concept: Inversion of Control and Dependency Injection

If you’re a newbie just starting to learn Spring, or even if you’ve heard a lot about Spring but not sure what it was, Martin Fowler has an excellent article about this: Inversion of Control and Dependency Injection pattern.

It was a bit old (written in 2004) but every single conceptual discussion still applies today.

If any of the following keyword doesn’t make any sense to you, then I beg you spare 20 minutes of your time to read this excellent article:

  • Inversion of Control
  • Dependency Injection
  • Service Locator

Posting JSON to Spring MVC Controller

Spring MVC can be setup to automatically bind incoming JSON string into a Java object. Firstly, ensure you have jackson-mapper-asl included on the classpath:


  org.codehaus.jackson
  jackson-mapper-asl
  1.9.13

Assuming the JSON string we want to bind represent a person object like this:

{
  name: "Gerry",
  age: 20,
  city: "Sydney"
}

Which will be bound into following Java class:

public class Person {
  private String name;
  private int age;
  private String city;
  // getters & setters ...
}

Declare the Spring MVC controller handler method like below. The handler method is mapped into path “addPerson” with method POST.

(value = "/addPerson", 
                method = RequestMethod.POST,
                headers = {"Content-type=application/json"})

public JsonResponse addPerson( Person person) {
  logger.debug(person.toString());
  return new JsonResponse("OK","");
}

Also pay attention to and the returned JsonResponse object. Here JsonResponse is a class to return the result of the addPerson operation.

public class JsonResponse {

  private String status = "";
  private String errorMessage = "";

  public JsonResponse(String status, String errorMessage) {
    this.status = status;
    this.errorMessage = errorMessage;
  }
}

When converted to JSON this will look like this:

{
  status : "OK",
  errorMessage : ""
}

Below is an example jQuery based javascript handler that posts into the above Spring MVC handler and observe the returned value:

$.ajax({
  type: "POST",
  url: "addPerson",
  data: JSON.stringify({ name: "Gerry", age: 20, city: "Sydney" }),
  contentType: 'application/json',
  success: function(data) {
    if(data.status == 'OK') alert('Person has been added');
    else alert('Failed adding person: ' + data.status + ', ' + data.errorMessage);
  }
});

Spring MVC Executor Service Anomaly Due to Holding HttpServletRequest for too Long

Encountered a strange problem with Spring MVC running on Tomcat 7 today. I had a with 1 max thread capacity on my application which wasn’t working as it supposed to. My Runnable task look something like this:

public class LongRunningTask implements Runnable {

  private HttpServletRequest request;
  
  public LongRunningTask(HttpServletRequest request) {
    this.request = request;
  }
  
  
  public void run() {
    // do something ..
  }

}

Notice I originally added a reference to HttpServletRequest with the intention of obtaining the remote host and address of the client. My controller class look something like this:


public class HomeController {

   private ThreadPoolTaskExecutor taskExecutor;

  (...)
  public String schedule(HttpServletRequest req, ...) {
    taskExecutor.submit(new LongRunningTask(req));
  }
}

With the hope that user’s get their response immediately while the actual work is still queued on the background.

Turns out this caused all sorts of strange behavior. Sometime the task will run, most of the time it will just sit in the queue forever / won’t even queue at all.

After further research and trial and error, I figured out this was because my runnable is holding a reference to HttpServletRequest. When I refactored the code the task executor work as per normal again.

I’ve came into a conclusion that holding to a HttpServletRequest object for longer than necessary is not a good practice.

Using Spring Data MongoDB

a great third party support based on standard MongoDB Java Driver.

Dependencies

Following dependencies are required. Check for latest version via Nexus Central Repository:

  1. spring-data-mongodb
    
      org.springframework.data
      spring-data-mongodb
      1.2.1.RELEASE
    
    
  2. mongo-java-driver
    
      org.mongodb
      mongo-java-driver
      2.11.1
    
    

Setup Mongo Connection, Template and Repository Scanning

This is similar idea with setting up db datasource. In this example the mongo database server is located at localhost:27017 (default). The MongoDB database name used is enrollment. The tag specifies the base package to scan for repository classes




  

  
    
    
  
  
  

Domain / Entity Class

Example on this post will be based on a simple Student entity class with only id and name field:

import org.springframework.data.annotation.Id;

public class Student {
  @Id private String id;
  private String name;
  // getters & setters..
}

Without explicit configuration this entity class will be mapped into MongoDB collection name student. To override this default behavior use (collection = "...") annotation.

Repository Class

Simply add an interface extending Spring Data Repository interface. Below sample uses PagingAndSortingRepository, which extends CrudRepository which provides most basic operation. The type parameter specifies this repository operates over Student entity, with the ID type being String. Spring Data will automatically generate an implementation of this interface.

public interface StudentRepository extends PagingAndSortingRepository {

}

This repository can now be injected into controllers:


("/student")
public class StudentController {

   private StudentRepository studentRepository;

  (method = GET)
  public String get(Model model) {
    Iterable students = studentRepository.findAll();
    return "student";
  }

  (value = "/new", method = POST)
  public String addNew(("student") Student student) {
    studentRepository.save(student);
  }

  ...
}

Read More

Learn more about Spring Data and MongoDB:

  • Spring Data MongoDB Reference Manual – http://static.springsource.org/spring-data/data-mongodb/docs/current/reference/html/index.html
  • MongoDB Manual – http://docs.mongodb.org/manual/

Cross Site Request Forgery (CSRF) Protection in Spring 3.1

Eyal Lupu has written an excellent article in his blog about mitigating Cross Site Request Forgery (CSRF) attack.

CSRF allows an attacker to create a fake form / link posting to a secured website. It exploits the fact you might have an active session from a secured website. For example, an attacker can create a fake form / link with all the data required to transfer money to his / her account without you realizing it.

This CSRF prevention techniques involes two components:

  1. Rendering a hidden form field with randomly generated token stored in session
  2. Ensuring the next post request came with matching token

The sample source code of this solution can be obtained from:

git clone https://github.com/eyal-lupu/eyallupu-blog.git

Session Scoped Beans in Spring

If your Spring application context is associated with a Java EE container (eg: created via ), you can set your bean in a session scope. This means every user starting a new http session will obtain a different copy of your bean.

Let’s see this in action. Below I have a ShoppingCart bean

public class ShoppingCart implements Serializable {
  private int userId;
  private List products;
  // getters & setters ...
}

Configure this to be a session scoped bean in spring xml configuration file:


  

The tag will cause Spring to create a proxy class over the ShoppingCart bean. This is critical because we want to inject our ShoppingCart to a singleton class (eg: Service / Controller classes) yet each user’s http session should get its own copy of the data.

In order for proxying to take effect you also need to include cglib library into your classpath.

I can now inject the ShoppingCart into HomeController:


("/home")
public class HomeController {

   private ShoppingCart shoppingCart;

  ...
}

One way to think about this is the proxy is actually a singleton mirror image of the ShoppingCart class, except each user coming from different HttpSession will see different data when they invoke the public methods. For each new HttpSession, on the first time user invokes one of the proxied method a new actual ShoppingCart bean instance is created behind the screen.

Entity Relationship On Hibernate JPA

This article is tested against Java EE 6, Hibernate 4.2.2.

One To Many Unidirectional Relationship

Unidirectional here means you can only obtain related entities from one side. For example supposed we have one to many Customer --> Account relationship, here’s what Customer entity look like


public class Customer {

  @Id
  
  private long id;

  private String name;

  
  (name = "customer_id")
  private Set accounts;

  // getters & setters..
}

Instead of Set, you can use List, however if you have more than one relationship in your entity class, you will get MultipleBagFetchException.

And This is what Account looks like. Notice there’s no reference to Customer object from Account.


public class Account {

  @Id
  
  private long id;
  
  private double balance;

  // Getters & Setters ..
}

One To Many Bidirectional Relationship

Similar to unidirectional except you can obtain relation from both direction. This is what Customer and Account look like:


public class Customer {

  @Id
  
  private long id;

  private String name;

  (mappedBy = "customer")
  private Set accounts;

  // getters & setters..
}

The “customer” on (mappedBy = "customer") refers to customer java property on Account entity.


public class Account {

  @Id
  
  private long id;
  
  private double balance;

  
  (name = "customer_id")
  private Customer customer;

  // Getters & Setters ..
}

The (name = "customer_id") annotation sets the database foreign key column name to be “customer_id”.

Lazy / Eager Loading

Lazy / Eager refers to when does entity relationship get populated. Eager means it will get populated as soon as the entity is obtained from database, where in Lazy it’s only populated when you request the relationship for the first time.

The default value for is LAZY, but for it’s EAGER. It’s a good practice to explicitly configure it so your code is easier to understand


public class Customer {
  ...
  (mappedBy = "customer", fetch = FetchType.LAZY)
  private Set accounts;
  ...
}

public class Account {
  ...
  (fetch = FetchType.EAGER)
  (name = "customer_id")
  private Customer customer;
  ...
}

LazyInitializationException: could not initialize proxy – no Session

Almost every Hibernate/JPA noobie struggle with this exception when they started learning (including myself). This is basically saying you’re tring to access unfetched data after transaction has been closed.

If you use Spring declarative transaction management, transaction start and finish mark are declared by simply annotating DAO method with . Let’s see a common failure where LazyInitializationException can happen.

Here’s your CustomerDAO class:


public class CustomerDAO {
  
  ext private EntityManager em;

  
  public List getAllCustomers() {
    List customers = em.createQuery("select c from Customer", 
      Customer.class).getResultList();
    return customers;
  }

Then on your controller you populate your Model object with list of Customers, and on your view your JSP tried to access Accounts associated with each customer:

Customer Info

Id: ${customer.id} Name: ${customer.name} Accounts:
  • Acc Id: ${acc.id}, Balance: ${acc.balance}

Since the transaction is already closed when CustomerDAO.getAllCustomers() method returns, this will throw LazyInitializationException.

My preferred strategy to overcome this problem is to prefetch the related entities on the DAO, so all the information we need is available on view level in detached state. Other strategy being opening a transaction / session while view is being generated (see: ). To achieve this, change the getAllCustomers() DAO method to use JPQL left join fetch syntax like this:


public class CustomerDAO {
  ...
  
  public List getAllCustomers() {
    List customers = em.createQuery(
      "select distinct c from Customer " +
      "left join fetch c.accounts", 
      Customer.class).getResultList();
    return customers;
  }
  ...
}

Now you can iterate and access all related accounts entities without exceptions.

Unit Testing Spring Bean Service With Mockito

The main idea of unit testing is quick compile-time checking that your code (somewhat) fulfills the business requirement.

A good unit testing practice is to not depend on any external system / dependencies. One way to substitute this external dependency is by using mocking tehcniques. Here I’ll go through unit testing a Spring bean service using .

Assuming you have a BankingService class that comes with a method to transfer money from one account to another. The method finds the Account object by its id using AccountsDAO repository class:


public class BankingService {

   private AccountsDAO accountsDAO;
  
  public void transfer(long fromAccountId, long toAccountId, double amount) throws Exception {
    Account fromAccount = accountsDAO.findById(fromAccountId);
    Account toAccount = accountsDAO.findById(toAccountId);
    
    fromAccount.setBalance(fromAccount.getBalance() - amount);
    toAccount.setBalance(toAccount.getBalance() + amount);
  }
}

AccountsDAO obtain the information from a persistent data store (most likely database), hence it is an external dependency. Here’s how to unit test this class:

  1. Ensure junit, spring-test and mockito dependencies are on the classpath
    
      junit
      junit
      4.7
      test
    
    
      org.springframework
      spring-test
      3.2.3.RELEASE
      test
    
    
      org.mockito
      mockito-core
      1.9.5
      test
    
    

  2. Setup BankingServiceTest.xml spring beans configuration file specific for our unit test. Note in here we created a mock AccountsDAO using Mockito. The order of mock creation here is important, if you place it at the bottom you will get autowiring error. I think this is because Spring couldn’t pre-determine the resulting type of the Mock object (it only looks as if it’s a org.mockito.Mockito bean type).
    
    
    
      
        
      
    
      
    
    
    

  3. Setup the unit test class. Notice the BankingService to test and the mock AccountsDAO are autowired into the unit test class
    (SpringJUnit4ClassRunner.class)
    ation("/BankingServiceTest.xml")
    public class BankingServiceTest {
    
       private BankingService bankingService;
       private AccountsDAO mockAccountsDAO;
      
      
      public void testTransfer() throws Exception {
        // Setup 2 accounts
        Account acc1 = new Account();
        acc1.setBalance(800.00);
        Account acc2 = new Account();
        acc2.setBalance(200.00);
        
        // Tell mock DAO to return above accounts when 1011 or 2041 is queried respectively
        when(mockAccountsDAO.findById(1011)).thenReturn(acc1);
        when(mockAccountsDAO.findById(2041)).thenReturn(acc2);
        
        // Invoke the method to test
        bankingService.transfer(1011, 2041, 500.00);
        
        // Verify the money has been transferred
        assertEquals(300.00, acc1.getBalance(), 0.001);
        assertEquals(700.00, acc2.getBalance(), 0.001);
      }
    }
    

  4. The when(..).thenReturn(..) syntax is where the magic happen. It will cause the mock object to return the Account we setup (as opposed of calling SQL to fetch it from database).

There are heaps more magic stuff you can do with Mockito. Checkout .

Source Code

Source code of this demo can be downloaded via git:

git clone https:///gerrytan/mycoolbank.git

Preserving Validation Error Messages on Spring MVC Form Post-Redirect-Get

Here is a simple Spring MVC guestbook form complete with validation error messages:

formvalidation

To code this, firstly add hibernate-validator to your classpath (pom.xml):


  org.hibernate
  hibernate-validator
  4.3.1.Final

And we’ll code the form as a java class. Notice we added few validators using annotations provided by hibernate-validators. The associated error message is also coded here :

public class MessageForm {
  (message = "Please provide your name")
  private String name;

  (message = "Please provide your email")
  (message = "Invalid email address")
  private String email;

  (min = 10, message = "Please enter at least 10 characters")
  private String message;

  // getters & setters..
}

Next we’ll create the JSP view containing html code for the form. Notice the usage of tag to display validation error messages

  • :
  • :
  • :

On our controller class, the method that serves the guestbook form first checks if the model attribute “messageForm” exists before creating a new one. This is to cover the scenario where validation fails and user has to be redirected back :


public class GuestbookController {

  /**
   * Serve guestbook form.
   */
  (value = "/", method = RequestMethod.GET)
  public String home(Model model) {
    if(!model.containsAttribute("messageForm")) model.addAttribute("messageForm", new MessageForm());
    return "guestbook";
  }

  // more code ..
}

On the message submission handler, notice the usage of annotation. This will trigger validation declared using annotation on our form class above. Validation errors can be checked from the associated BindingResult object. Here if error occurs we redirect the user back to the form and display the error messages (pay attention to the “redirect:” prefix). Notice the BindingResult object is passed via RedirectAttributes using org.springframework.validation.BindingResult.messageForm name, this will ensure the messages can be accessed using tags.

...
  /**
   * Form post handler
   */
  (value = "/", method = RequestMethod.POST)
  public String send(
       ("messageForm") MessageForm messageForm, 
      BindingResult binding, 
      RedirectAttributes redirectAttributes) {
  
    // Redirect back into form page if errors detected
    if (binding.hasErrors()) {
      redirectAttributes.addFlashAttribute("org.springframework.validation.BindingResult.messageForm", binding);
      redirectAttributes.addFlashAttribute("messageForm", messageForm);
      return "redirect:/";
    }
  
    return "redirect:/result";
  }
...

And finally display a success message if no errors

...
  /**
   * Result page, simply displays 'message has ben sent'
   */
  (value = "/result", method = RequestMethod.GET)
  public String result() {
    return "result";
  }
...

Get The Source Code

Source code for this blog is available to checkout via git:

git clone https:///gerrytan/formvalidation1.git

To run it, simply use mvn clean tomcat:run, and point your browser to http://localhost:8080/formvalidation1

Thanks Oscar for describing the BindingResult preservation techniques on redirection.

Spring MVC File Upload Form

Objective : Setup a form with file upload field

Environment

  • Spring MVC 3.2.3.RELEASE
  • Commons Fileupload 1.3

First let’s code the JSP view of the form. Note below enctype=”multipart/form-data” setting is important, it tells the browser to post the form data as multipart.


File:

Above JSP will result in a simple file upload form like this:

fileuploadform

Then add commons-fileupload 1.3 maven dependency to your pom.xml:


  commons-fileupload
  commons-fileupload
  1.3

And configure CommonsMultipartResolver on your spring context. The bean id name is important. Also below I configured it to have maximum file size of 1 mb (1000000 bytes)


  

Now we’re ready to code the controller handler method. The uploaded file is automatically bound into a object from which you can obtain input stream.

(value = "/", method = RequestMethod.POST)
public String upload(("myfile") MultipartFile myFile) {
  logger.info("Received file of size " + myFile.getSize() + " bytes");
  InputStream inputStream = myFile.getInputStream();
  // .. do something with inputStream
  inputStream.close();
  return "home";
}