Tag Archives: spring framework

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";
}

Spring MVC + Hibernate + MySQL Quick Start From Scratch

This is a tutorial to build a very simple pizzashop Spring MVC, Hibernate and MySQL application. The main page shows all pizza rows stored on a database table:

03

Technology in Java world moves very fast. Using straight Hibernate might no longer be preferable since Java EE 5 introduces JPA (Java Persistence API) but it’s still good to learn anyway. Spring MVC and Hibernate is one of the most popular Java libraries used out there.

Tools / Environment Required
If you’re just starting fresh and don’t have most of the tools below just install JDK, STS (Springsource Tools Suite) and MySQL server, everything else is bundled within them.

Project Setup and Boilerplate

  1. First, create new Maven project on STS. Skip archetype selection. Pick maven group id, artifact id and select packaging to war.01 02

  2. By default Maven will use JDK 1.5, re-configure it to use 1.6. Add following maven-compiler-plugin section to pom.xml under element. Ensure the change takes effect by updating maven project settings (right click on project -> Maven -> Update project…).
    
      
        
          org.apache.maven.plugins
          maven-compiler-plugin
          3.1
          
            1.6
            1.6
          
        
      
    
    

  3. Add Spring, Hibernate, Java EE and MySQL maven dependencies to pom.xml. Place following under element.
    
      3.2.3.RELEASE
      4.2.2.Final
    
    
    
      
      
        org.springframework
        spring-context
        ${spring.version}
      
      
        org.springframework
        spring-webmvc
        ${spring.version}
      
      
        org.springframework
        spring-orm
        ${spring.version}
      
      
      
      
        org.hibernate
        hibernate-core
        ${hibernate.version}
      
      
      
      
        javax.servlet
        servlet-api
        2.5
        provided
      
      
        jstl
        jstl
        1.2
      
      
      
      
        commons-dbcp
        commons-dbcp
        1.4
      
      
        mysql
        mysql-connector-java
        5.1.25
      
      
    
    

  4. Create a web.xml descriptor file with Spring MVC servlet setup on it, place it on src/main/webapp/WEB-INF
    
    
    
      
        appServlet
        org.springframework.web.servlet.DispatcherServlet
        
          contextConfigLocation
          /WEB-INF/servlet-context.xml
        
        1
      
       
      
        appServlet
        /
      
      
    
    

  5. Create src/main/webapp/WEB-INF/servlet-context.xml Spring bean config file for dispatcher servlet. We configure few important stuffs in here:
    
    
    
      
      
    
      
      
        
        
      
      
      
      
      
      
      
        
        
        
        
        
      
      
      
      
        
        
          
            com.gerrytan.pizzashop
          
        
        
          
            hibernate.dialect=org.hibernate.dialect.MySQLDialect
          
        
      
      
      
      
        
      
      
      
      
    
    
    


The Business Functionality

  1. Now all the boilerplate code done, we can start coding the business functionality. For this simple app we will have a pizza database table with just id, name and price column. Create the Pizza entity class representing the table
    package com.gerrytan.pizzashop;
    // imports ..
    
    
    (name = "pizza")
    public class Pizza {
      @Id  private long id;
      private String name;
      private double price;
      /* getters & setters */
    }
    

  2. Create a DAO class to obtain Pizza entity persisted on database. Note that we won’t create service layer classes for the sake of simplicity (on real-life complex business application adding service layer is a good practice).
    package com.gerrytan.pizzashop;
    // imports..
    
    
    s({"unchecked", "rawtypes"})
    public class PizzaDAO {
       private SessionFactory sessionFactory;
      
      /**
       *  annotation below will trigger Spring Hibernate transaction manager to automatically create
       * a hibernate session. See src/main/webapp/WEB-INF/servlet-context.xml
       */
      
      public List findAll() {
        Session session = sessionFactory.getCurrentSession();
        List pizzas = session.createQuery("from Pizza").list();
        return pizzas;
      }
    }
    

  3. Create a Spring MVC controller to handle request from the main page. Note that PizzaDAO reference is injected, and after collection of Pizza entity objects are obtained it’s passed to the view using Model object.
    package com.gerrytan.pizzashop;
    // imports..
    
    
    ("/")
    public class PizzaController {
      
       private PizzaDAO pizzaDAO;
      
      /**
       * This handler method is invoked when
       * http://localhost:8080/pizzashop is requested.
       * The method returns view name "index"
       * which will be resolved into /WEB-INF/index.jsp.
       *  See src/main/webapp/WEB-INF/servlet-context.xml
       */
      (method = RequestMethod.GET)
      public String list(Model model) {
        List pizzas = pizzaDAO.findAll();
        model.addAttribute("pizzas", pizzas);
        return "index";
      }
    }
    

  4. Add a JSP view to list all the pizza entities passed by the controller
    src/main/webapp/WEB-INF/index.jsp

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    
    
    
    
    Pizzashop
    
    
            

    List of All Pizzas

    • ${p.id} - ${p.name} - ${p.price}

  5. And finally prepare MySQL pizzashop database schema:
    CREATE SCHEMA `pizzashop`;

    And pizza table:

    CREATE  TABLE `pizzashop`.`pizza` (
      `id` BIGINT NOT NULL AUTO_INCREMENT ,
      `name` VARCHAR(45) NULL ,
      `price` DOUBLE NULL ,
      PRIMARY KEY (`id`) );
    

    And insert some data into it

    INSERT INTO `pizzashop`.`pizza` (`id`, `name`, `price`) VALUES ('I', 'Italian', '7.5');
    INSERT INTO `pizzashop`.`pizza` (`id`, `name`, `price`) VALUES ('2', 'Thin Crust', '6');
    INSERT INTO `pizzashop`.`pizza` (`id`, `name`, `price`) VALUES ('3', 'Pepperoni', '6.2');
    

    It is assumed you have MySQL server running on your local machine (localhost) on the default port 3306. The name of the schema is pizzashop and table pizza. Have a look at Spring beans configuration section above to reconfigure this.

Running The Code

  1. The easiest way to run your code is using in-memory Maven Tomcat plugin. It will launch on-the-fly Tomcat server with your code deployed. Make sure your project is selected on the project exploded and setup a maven run configuration on STS. Go to Run -> Run Configurations.. and create a new maven build entry like this:
    maven goal
  2. Click Run and navigate your browser to http://localhost:8080/pizzashop

Download The Source Code

Source code for this demonstration can be obtained using git:

git clone https://bitbucket.org/gerrytan/pizzashop.git -b basic

Congratz!

Well done on making it this far. Hopefully that was a quick and nice introduction to Spring MVC + Hibernate + MySQL and you can see how the tedious database to java class mapping is now simplified. You might have lots of questions in your mind by now — feel free to ask in the comment section below. Following are few official references and community article links you can browse around:

See Also

Java EE & Spring Cheatsheet

JSTL 1.2 Core JSP Taglib (aka c tag)

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

JSTL implementation jar has to exist on the classpath, eg add following dependency (in provided scope if container doesn’t provides it)


  jstl
  jstl
  1.2

See this blog post for more info.

Spring Taglib

  • Spring:
    <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
  • Form:
    <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

JSTL fmt Taglib

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

web.xml deployment descriptor

  • v2.3
    
    
    
      
    
    
  • v3.0
    
    
        
    
    

Commons DBCP / MySQL Spring Bean Config



  
  
  
  
  
  

Hibernate / MySQL Session Factory & Transaction Manager Spring Bean Config



  
  
    
      com.gerrytan.hibernatefiddle
    
  
  
    
      hibernate.dialect=org.hibernate.dialect.MySQLDialect
    
  




  

Log4j Properties File

# Root logger option
log4j.rootLogger=INFO, stdout

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n

This will print log in following format:

2013-06-26 10:15:35 DEBUG com.gerrytan.hibernatefiddle.StudentDAO:21 - StudentDAO created

To create file logger, limited to 5 file with max size 1000KB:

# Root logger option
log4j.rootLogger=WARN, file
 
# Rolling file appender
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=MyLog.log
log4j.appender.file.MaxFileSize=1000KB
log4j.appender.file.MaxBackupIndex=5
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n

If you’re using tomcat the log file typically goes to bin folder. To place it on logs you can use:

log4j.appender.file=${catalina.base}/logs/MyLog.log

Hibernate Logging

log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.engine.transaction=DEBUG

On Hibernate 3 or earlier transaction logger is:

log4j.logger.org.hibernate.transaction=DEBUG

Installing Spring Security On Spring MVC Project

These are steps required to install Spring Security for a form authentication implementation on a Spring MVC project.

  1. Maven Dependencies.

    
            org.springframework.security
            spring-security-core
            3.1.4.RELEASE
    
    
            org.springframework.security
            spring-security-config
            3.1.4.RELEASE
    
    
            org.springframework.security
            spring-security-web
            3.1.4.RELEASE
    
    
  2. Add Spring Security filter to web.xml
    
    
            springSecurityFilterChain
            org.springframework.web.filter.DelegatingFilterProxy
    
    
    
            springSecurityFilterChain
            /*
    
    
  3. Add a security-context.xml spring beans config file. You can place all your security config on root application context xml but separating it would produce clearer code without namespace prefix clutter
    
    
    
    
    
    
    
    
  4. Add basic HTTP form authentication and provider as seen on Spring reference manual