Google App Engine JAX-RS REST service

In this article you will learn how to create a REST service using JAX-RS reference implementation (Jersey) and deploy it on Google AppEngine.

Prerequisites 

For this tutorial you will need:
  • a Google AppEngine account
  • Eclipse Galileo (3.5.x)
  • Google App Engine SDK for Java
    • Install the Google Plugin for Eclipse as documented here (Check that you are using the release 1.3.1 of the GAE Java SDK, if not download it and configure the plugin to use it)
    • it is also useful to have the AppEngine documentation locally, you can download it from here.
  • JAX-RS Reference Implementation, be sure you take the Jersey 1.1.5 release. You can download it from here
    • Unzip the file in a directory that we will call $JERSEY_HOME
  • JAXB 2.2 Implementation to simplify the marshalling/unmarshalling of the XML, and also facilitate the JSON support. Download it from here
    • Install it using thejava -jar JAXB2_20091104.jar command. The installation directory of JAXB will be called $JAXB_HOME



Creating new application

To create a new App Engine project in Eclipse:

  1. Click on the "New Web Application Project" button in the toolbar . It is also possible to do it using the menu File > Web Application Project
  2. The "Create a Web Application Project" wizard opens:
  • Project Name: EmployeeService
  • Package : com.grallandco.employee.service
  • Uncheck "Use Google Web Toolkit"
  • Check that the SDK version your are using is "App Engine 1.3.0"; if not configure the project to use it.
  • The screen should look like the following screen :
  • Click Finish
  • The project should look like the following screen :

Running the application

The App Egine SDK, installed with the Eclipse plugin contains a Web server (based on Jetty), that could be used for testing and debugging. To test that your application has been created correctly select the menu Run > Run As > Web Application. I personnaly most of the time run my server using the debug command Run > DebugAs > Web Application. In debug mode you can change source code and test is without restarting the server.

The web server is starting automatically, you should see the following message in the Eclipse console

The server is running at http://localhost:8080/

You can access the application, and the sample servlet that has been created using the URL: http://localhost:8080/employeeservice

To stop the server, click on the terminate button
in the Eclipse console.

Configuring the REST support in the application

To be able to create and run REST services in your application you need to:

  • Add the JAX-RS, JAXB Jars in your project and application
  • Configure the web application (web.xml) to handle REST requests

Add JAX-RS, JAXB to your project

  1. Right click on the project and select menu entry Build Path > Configure Build Path…
  2. Click on the Add External JARs button
  3. Select all the JARs located in $JERSEY_HOME/lib and $JAXB_HOME/lib folders. You can for better visibility and reuse create a user library with all these JARs
  4. You also need to copy the JARs in the web-inf/lib directory of your application, this step is mandatory to be sure that the JARs are included in the application when deployed to App Engine.
    Note: I do not like this step. I would prefer to do that by configuration of the build path, to automatically add the JARs to the WEB-INF/lib directory when executing/deploying the application. Unfortunately I did not find the way to do it, so if you know it, feel free to post a comment and I will update the article.

Configure the web application

In this step you will register a new URI to handle REST requests. To do that you need to register a new servlet that is using the Jersey API and configure it to a specific URI (eg: /ressources and/or /rest) and configure what are the Java packages that contain the REST implementation classes. So you need to modify the web.xml of your application with the following entries:

  <servlet>
    <servlet-name>Jersey Web Application</servlet-name>
     <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
     <init-param>
     <param-name>com.sun.jersey.config.property.packages</param-name>
     <param-value>com.grallandco.employee.service.rest.impl</param-value>
     </init-param>
     <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey Web Application</servlet-name>
    <url-pattern>/resources/*</url-pattern>
  </servlet-mapping>
   <servlet-mapping>
    <servlet-name>Jersey Web Application</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
This servlet that will answer to the /resources/ and /rest/ URL. The configuration parameter com.sun.jersey.config.property.packages is used by Jersey to list the packages where REST services implementation are located.Note that you can put as many package as you need to, you just need to separate the package names by a ; 


Creating a simple REST Service to test the environment

The project is now ready to contain REST service. It is time to create one.Create for example the class com.grallandco.employee.service.rest.impl.HelloWorldResource, be sure to use the package name that you have configured in the web.xml for the Jersey servlet, based on the configuration we have made in previous step the package is com.grallandco.employee.service.rest.impl

Here a sample class with the JAX-RS annotations:

package com.grallandco.employee.service.rest.impl;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
@Path("/hr/")
public class EmployeeResource {
 
 @GET
 @Produces("text/plain")
 @Path("/employee") 
 public String getEmployee() {
        return "Hello World!";
    }
}

You should be able to test it, stop the server and run it again, enter the following URL in your browser:

http://localhost:8080/resources/hr/employee

or

http://localhost:8080/rest/hr/employee

Deploying the application to Google App Engine

Before deploying the application you need to register a new application in Google App Engine using the Administartion Console, see the documentation
here. In my example I have used " tugdual" as Application ID.

You can easily now deploy the application to Google App Engine by clicking on the "Deploy App Engine Project" button available in the Eclipse toolbar.

To be able to deploy your application to Google App Engine, you need to check that your application can be registered, the application ID is stored in the WEB-INF/lib/appengine-web.xml.

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
 <application>[your-application-id]</application>   
 <version>1</version>    
 <!-- Configure java.util.logging -->
  <system-properties>
   <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
 </system-properties>    
</appengine-web-app>

The App Engine deploy button prompts you for multiple informations: username (your Google account) and password.

When the deployment is complete you can access your application using the following URL:

http://%5Byour-application-id%5D.appspot.com/resources/hr/employee

or

http://%5Byour-application-id%5D.appspot.com/rest/hr/employee

Ading XML and JSON support to the service

Let’s now add new method to manipulate an "Employee" object using the service, and the data format should be based on JSON and XML. This is where JAXB is useful, since it allows easily to transform marshall/unmarshall Java objects in XML -obviously- and JSON (cool isn’t!)

Creating an Employee Class

Start with the creation of a new class to manipulate Employee data, this is a very simple Java class that could look like the following code:

package com.grallandco.employee.service.model;
import java.util.Date;

public class Employee {
    private String firstName;
    private String lastName;
    private Date hireDate;
    private String email;   
    public Employee(String firstName, String lastName, Date hireDate, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.hireDate = hireDate;
        this.email = email;
    }
    public Employee() {}
    public String getFirstName() {
 return firstName;
 }
    public void setFirstName(String firstName) {
 this.firstName = firstName;
 }
    public String getLastName() {
 return lastName;
 }
    public void setLastName(String lastName) {
     this.lastName = lastName;
 }
    public Date getHireDate() {
 return hireDate;
 }
    public void setHireDate(Date hireDate) {
 this.hireDate = hireDate;
 }
    public String getEmail() {
        return email;
 }
    public void setEmail(String email) {
        this.email = email;
   }
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("First: ").append(getFirstName());
        sb.append(" - Last: ").append(getLastName());
        sb.append(" - Date: ").append(getHireDate());
        sb.append(" - Email: ").append(getEmail());
        return sb.toString();
    }
}

When implementing your "real" application with some persistence layer this POJO is the one as JDO/JPA entity.

Create a Converter class for your entity

I usually encapsulate all the transformation in some converter class, like that I do not directly couple my business class to the serialisation mechanism. (So I do that for classes and lists of classes). So instead of adding the JAXB annotations to the Employee class itself, let’s create an EmployeeConverter class that will be responsible of the transformation and used by your REST service.

package com.grallandco.employee.service.converter;

import java.util.Date;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import com.grallandco.employee.service.model.Employee;

@XmlRootElement(name = "employee")
public class EmployeeConverter {
 private Employee entity = null;
 public EmployeeConverter() {
 entity = new Employee();
 }

 public EmployeeConverter(Employee entity) {
 this.entity = entity;
 }

 @XmlElement
 public String getFirstName() {
 return entity.getFirstName();
 }

 @XmlElement
 public String getLastName() {
 return entity.getLastName();
 }

 @XmlElement
 public Date getHireDate() {
 return entity.getHireDate();
 }

 @XmlElement
 public String getEmail() {
 return entity.getEmail();
 }

 public Employee getEmployee() {
 return entity;
 }

 public void setFirstName(String firstName) {
 entity.setFirstName(firstName);
 }

 public void setHireDate(Date hireDate) {
 entity.setHireDate(hireDate);
 }

 public void setLastName(String email) {
 entity.setEmail(email);
 }

 public void setEmail(String lastName) {
 entity.setLastName(lastName);
 }
}

You can now update your service to use this utility/converter class to return XML or JSON ojbect based on the content type of the request.

Add support to JSON and XML to your REST service

You need to change the EmployeeRessource class, to change the signature and add new annotations of the getEmployee() method.

The annotation you are adding:

  • @Produces({"application/xml", "application/json"}) : indicates which type of content will be produced by the service. Based on the type of the request.
  • @Path("/employee/{employeeEmail}/") : change the Path to indicate a Path parameter, here for example the URL can accept an email in the URI – not the best example, but you get the point…
  • public EmployeeConverter getEmployee( @PathParam ("employeeEmail") String email) : change the type returned by the method and take a parameter as String that match the Path param defined in the @Path annotation

Here the complete class code:

package com.grallandco.employee.service.rest.impl;

import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import com.grallandco.employee.service.converter.EmployeeConverter;
import com.grallandco.employee.service.model.Employee;

@Path("/hr/")
public class EmployeeRessource {

 
 @GET
 @Produces({"application/xml", "application/json"})
 @Path("/employee/{employeeEmail}/") 
 public EmployeeConverter getEmployee( @PathParam ("employeeEmail") String email) {
 //dummy code
 Employee emp = new Employee();
 emp.setEmail(email);
 emp.setFirstName("John");
 emp.setLastName("Doe");
 EmployeeConverter converter = new EmployeeConverter(emp);
 return converter;
 } 
}

Test the service

You can now run the server locally and test the service

http://localhost:8080/resources/hr/employee/tug@grallandco.com

This will return an XML document.

If you want to test the JSON call you have multiple choice:

  • Using following command
tgrall$ curl -H "Accept: application/json" http://localhost:8080/resources/hr/employee/tug@grallandco.com
{"email":"tug@grallandco.com","firstName":"John","lastName":"Doe"}
  • Using an HTTP client that allows your to configure/set the HTTP request completely, I am using the Poster Firefox Plugin
  • Using some Javascript code in an application

You can repeat the test on your deployed application on Google App Engine.

Conclusion

In this article you have learned how to create and deploy a new REST Service on Google App Engine. This service has been created with the JAX-RS Reference Implementation the Jersey project. In the next article you will learn how to add persistence and create a CRUD Rest service on Google App Engine.


Reference:
Create and Deploy a JAX-RS REST service on Google App Engine from our
JCG partner Tugdual Grall at the
Tug’s Blog blog.

Source : http://www.javacodegeeks.com/2012/05/google-app-engine-jax-rs-rest-service.html

How to use RestTemplate with Basic Authentication in Spring

This article shows how to use Springs
RestTemplate to
consume a RESTful Service secured with Basic Authentication; the article is part of an in depth
series on REST with Spring.

The REST with Spring series:


Setting up the RestTemplate in Spring

Bootstraping the
RestTemplate into the Spring context can be done by simply declaring a bean for it; however, setting up the
RestTemplate with
Basic Authentication will require manual intervention, so instead of declaring the bean directly, a Spring
FactoryBean will be used for more flexibility. This factory will create and configure the template on initialization:

@Component
public class RestTemplateFactory implements
    FactoryBean< RestTemplate >, InitializingBean{
   private RestTemplate restTemplate;

   public RestTemplate getObject(){
      return restTemplate;
   }
   public Class< RestTemplate > getObjectType(){
      return RestTemplate.class;
   }
   public boolean isSingleton(){
      return true;
   }
   public void afterPropertiesSet(){
      restTemplate = new RestTemplate(
       new HttpComponentsClientHttpRequestFactoryBasicAuth
        ( new HttpHost(host, port, protocol) );
   }
}

The
host and
port values should be dependent on the environment – allowing the client the flexibility to define one set of values for integration testing and another for production use. The values can be managed by the
first class Spring support for properties files.

Basic Authentication for the RestTemplate

Once Basic Authentication is set up for the template, each request will be sent
preemptively containing the full credentials necessary to perform the authentication process. The credentials will be encoded and will use the
Authorization HTTP Header, in accordance with the specs of the Basic Authentication scheme. An example would look like this:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==


Manual management of the Authorization HTTP header

The process of creating the
Authorization header is relatively straightforward for Basic Authentication, so it can pretty much be done manually with a few lines of code:

HttpHeaders createHeaders( String username, String password ){
   return new HttpHeaders(){
      {
         String auth = username + ":" + password;
         byte[] encodedAuth = Base64.encodeBase64( auth.getBytes() );
         String authHeader = "Basic " + new String( encodedAuth );
         set( "Authorization", authHeader );
      }
   };
}

Then, sending a request becomes just as simple:

restTemplate.exchange
 (uri, HttpMethod.POST, new HttpEntity<T>(createHeaders(username, password)), clazz);


Automatic management of the Authorization HTTP header

Both Spring 3.0 and 3.1 have very good support for the Apache HTTP libraries:

  • Spring 3.0, the CommonsClientHttpRequestFactory integrated with the now end of lifed HttpClient 3.x
  • Spring 3.1 introduced support for the current HttpClient 4.x via HttpComponentsClientHttpRequestFactory (support added in the JIRA SPR-6180)

Let’s start setting things up with HttpClient 4 and the newly introduced support from Spring 3.1. The
RestTemplate accepts the HTTP request factory in it’s constructor – allowing a factory that supports Basic Authentication to be passed into the template – so far, so good. However, using the existing
HttpComponentsClientHttpRequestFactory will prove to be difficult, as the architecture of
RestTemplate was designed
without good support for
HttpContext – an instrumental piece of the puzzle.

Fortunately this is not without a solution, but first, some details on how to do Basic Authentication with the HttpClient library itself. Doing preemptive Basic Authentication with HttpClient 4.x is
a bit of a burden: the authentication info is cached and the process of setting up this authentication cache is very manual and unintuitive:

private HttpContext createHttpContext() {
    // Create AuthCache instance
    AuthCache authCache = new BasicAuthCache();
    // Generate BASIC scheme object and add it to the local auth cache
    BasicScheme basicAuth = new BasicScheme();
    authCache.put(targetHost, basicAuth);
    // Add AuthCache to the execution context
    BasicHttpContext localcontext = new BasicHttpContext();
    localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
    return localcontext;
}

HttpResponse response = httpclient.execute
 (targetHost, new HttpGet("/"), createHttpContext());

Now, this
HttpContext needs to be hooked up to the
RestTemplate, so that requests created via the template can benefit from the Basic Authentication support. As mentioned before, this is not an easy as it should be – the entire
HttpComponentsClientHttpRequestFactory needs to be
subclassed and the
createHttpContext method
overridden:

public class HttpComponentsClientHttpRequestFactoryBasicAuth
 extends HttpComponentsClientHttpRequestFactory {
   HttpHost host;

   public HttpComponentsClientHttpRequestFactoryBasicAuth(HttpHost host) {
      super();
      this.host= host;
   }
   protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
      return createHttpContext();
   }
   private HttpContext createHttpContext() {
      ...
   }
}

And with that, everything is in place – the
RestTemplate will now be able to support the Basic Authentication scheme; a simple usage patter would be:

HttpComponentsClientHttpRequestFactory requestFactory =
 (HttpComponentsClientHttpRequestFactory) restTemplate.getRequestFactory();
DefaultHttpClient httpClient =
 (DefaultHttpClient) requestFactory.getHttpClient();
httpClient.getCredentialsProvider().setCredentials(
 new AuthScope(host, port, AuthScope.ANY_REALM),
  new UsernamePasswordCredentials("name", "pass"));

For an in depth discussion on how to secure the RESTful Service itself,
check out this article.

Maven dependencies

The following Maven dependencies are required for the
RestTemplate itself and for the HttpClient library:

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>3.1.1.RELEASE</version>
</dependency>

<dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   <version>4.1.3</version>
</dependency>

Optionally, if the HTTP
Authorization header is constructed manually, then an additional library is required for the encoding support:

<dependency>
   <groupId>commons-codec</groupId>
   <artifactId>commons-codec</artifactId>
   <version>1.6</version>
</dependency>


Conclusion

Although the 3.x branch of development for Apache HttpClient has reached end of life for a while now, and the Spring support for that version has been fully deprecated, much of the information that can be found on
RestTemplate and security still doesn’t account for
the current HttpClient 4.x releases. This article is an attempt to change that through a detailed, step by step discussion on how to set up Basic Authentication with the
RestTemplate and how to use it to consume a secured RESTful Service.

For the next article, the focus will be on setting up
Digest Authentication in the same way. To go beyond the code samples in the article with a production ready implementation of both the consuming side, examined here, but also the actual RESTful service, check out the
REST github project.


Reference:
How to use RestTemplate with Basic Authentication in Spring from our
JCG partner Eugen Paraschiv at the
baeldung blog.

Source : http://www.javacodegeeks.com/2012/05/how-to-use-resttemplate-with-basic.html

Cloud SQL: pick the plan that fits your app

One of the most requested additions to the Google App Engine platform has been a SQL database, and more than 10,000 developers have signed up for the Google Cloud SQL service since the preview launch last October. Google Cloud SQL automatically provisions and maintains your databases, allowing you to focus on your applications and services.






Since launch, we’ve been busy working on improving the performance, and adding features like scheduled backups and multihoming to increase availability and improve performance. We are also now offering more powerful instances with up to 4GB of RAM. 



Today we are announcing our pricing, which will take effect on June 12th with two options to choose from:

  • For developers who want to try out the service, or who have lightweight applications – we offer a flexible “per use” pricing scheme. For example, you can get started with a cloud hosted MySQL database for around a dollar per month. You pay for just what you use.
  • For developers with more traffic, there are packages that offer a discount and help you predict your costs in advance.


Google Cloud SQL is currently in limited preview. If you want to give us a try, start here https://developers.google.com/cloud-sql/.

Posted by Joe Faith on behalf of the Google Cloud SQL team

Source : http://googleappengine.blogspot.ca/2012/05/cloud-sql-pick-plan-that-fits-your-app.html

Spring MVC 3 Controller for MyBatis CRUD operation

Till now we have created CRUD database service for the domain class “
User” and alsointegratedMyBatis configuration with Spring Configuration file. Next, we will create an web page using Spring MVC to use MyBatis CRUD service to perform operations to database.

  1. Creating DAO class using MyBatis 3 that will help to perform CRUD operations on database.
  2. Setting Environment for integrating MyBatis 3 and Spring MVC 3 frameworks.
  3. Creating Spring MVC 3 controller for performing CRUD operation.

So, in this part we will go through following sessions that will make us able to create the user interface for the example using Spring MVC and MyBatis CRUD service:

  1. The Spring Form Validator
  2. The Spring MVC Controller
  3. The jsp page andJavaScriptfiles used to perform UI creation
  4. And the last Spring MVC configuration file


The Spring Form Validator

First of all we will see the form validator used in this example. Here is the code:

package com.raistudies.validator;

import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import com.raistudies.domain.User;

@Component
public class RegistrationValidator implements Validator {

        public boolean supports(Class<?> c) {
                return User.class.isAssignableFrom(c);
        }

        public void validate(Object command, Errors errors) {
                ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "field.name.empty");
                ValidationUtils.rejectIfEmptyOrWhitespace(errors, "standard", "field.standard.empty");
                ValidationUtils.rejectIfEmptyOrWhitespace(errors, "age", "field.age.empty");
                ValidationUtils.rejectIfEmptyOrWhitespace(errors, "sex", "field.sex.empty");
                User usrBean = (User)command;
                if(!isNumber(usrBean.getAge().trim()))
                        errors.rejectValue("age", "field.age.NAN");
        }

        private boolean isNumber(String str){
            for (int i = 0; i < str.length(); i++) {

                //If we find a non-digit character we return false.
                if (!Character.isDigit(str.charAt(i)))
                return false;
                }

                return true;
        }
}

As you can see, we have put some restrictions on the form values like every field should have values and the value in “
age” field should be number. You can add more restrictions on the form values as you need from the
validate() method of this class. The contain of the error message values are defined in the property file
messages.properties, which is as bellow:

field.name.empty=Name field is mandatory.
field.standard.empty=Standard field is mandatory.
field.age.empty=Age field is mandatory.
field.sex.empty=Sex field is mandatory.

field.age.NAN=Age should be a number.

That is all for the form validation part, now we will see controller part.

The Spring MVC Controller

The controller will project the request from browser to MyBatis services. Bellow is the code:

package com.raistudies.controllers;

import java.util.List;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.raistudies.domain.User;
import com.raistudies.persistence.UserService;
import com.raistudies.validator.RegistrationValidator;

@Controller
@RequestMapping(value="/registration")
public class RegistrationController {

        private RegistrationValidator validator = null;
        private UserService userService = null;

        @Autowired
        public void setUserService(UserService userService) {
                this.userService = userService;
        }

        public RegistrationValidator getValidator() {
                return validator;
        }

        @Autowired
        public void setValidator(RegistrationValidator validator) {
                this.validator = validator;
        }

        @RequestMapping(method=RequestMethod.GET)
        public String showForm(ModelMap model){
                List<User> users = userService.getAllUser();
                model.addAttribute("users", users);
                User user = new User();
                user.setId(UUID.randomUUID().toString());
                model.addAttribute("user", user);
                return "registration";
        }

        @RequestMapping(value="/add", method=RequestMethod.POST)
        public ModelAndView add(@ModelAttribute(value="user") User user,BindingResult result){
                validator.validate(user, result);
                ModelAndView mv = new ModelAndView("registration");
                if(!result.hasErrors()){
                        userService.saveUser(user);
                        user = new User();
                        user.setId(UUID.randomUUID().toString());
                        mv.addObject("user", user);
                }
                mv.addObject("users", userService.getAllUser());
                return mv;
        }

        @RequestMapping(value="/update", method=RequestMethod.POST)
        public ModelAndView update(@ModelAttribute(value="user") User user,BindingResult result){
                validator.validate(user, result);
                ModelAndView mv = new ModelAndView("registration");
                if(!result.hasErrors()){
                        userService.updateUser(user);
                        user = new User();
                        user.setId(UUID.randomUUID().toString());
                        mv.addObject("user", user);
                }
                mv.addObject("users", userService.getAllUser());
                return mv;
        }

        @RequestMapping(value="/delete", method=RequestMethod.POST)
        public ModelAndView delete(@ModelAttribute(value="user") User user,BindingResult result){
                validator.validate(user, result);
                ModelAndView mv = new ModelAndView("registration");
                if(!result.hasErrors()){
                        userService.deleteUser(user.getId());
                        user = new User();
                        user.setId(UUID.randomUUID().toString());
                        mv.addObject("user", user);
                }
                mv.addObject("users", userService.getAllUser());
                return mv;
        }
}

The controller is using two beans for the CRUD operations, one is 
RegistrationValidator that we say above to validate the form data and other is 
UserService that we created in our previous part using MyBatis 3 to perform database operations on the form data. Both the beans will beauto wiredby spring using setter injection.

The controller have following operation methods that handles CRUD requests on form data:

  • showForm() :This operations will show up the form for the first time that is why we have put method type as RequestMethod.GET The method will also provide all available users in database using getAllUser() method of UserService to show up on the table bellow the form.
  • add() : This operation will handle the create operation. First of all it will validate the form data and if no erroroccurthen it will save form data to database to create a new user usingsaveUser()method of UserService. It will also bind a new User object with the form.
  • update() : update method will update the user detail to the database using updateUser() method of UserService and before that it will validate the data using RegistrationValidator.
  • delete() :This method is used to delete the user from database and take helps from the deleteUser() method of UserService for this.

The jsp page and JavaScript files used to perform UI creation

In this session, we will see user interface part of the example. We are to create a web page like the following :

Spring MVC and MyBatis 3 Integration – User Form

UI functionality:

  • The “Save Changes” button will be used to create a new user or to update an existing user.
  • The “New User” button will be used to set the form to create a new user.
  • The “Delete User” button will be used to delete a user who’s details are showing in the form
  • Clicking on any row will bring the corresponding row data to form fields for update or delete.

Let us see jsp code corresponding to the web page:

</div>
<div>
<pre><!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ page session="true" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html xmlns="http://www.w3.org/1999/xhtml">
        <head>
                <title>Hello World with Spring 3 MVC</title>
                <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
                <script type="text/javascript" src='<c:url value="/resources/common.js"/>'></script>
                <script type="text/javascript" src='<c:url value="/resources/registration.js"/>'></script>
                <script type="text/javascript">
                        var projectUrl = '<c:url value="/"/>';
                        if(projectUrl.indexOf(";", 0) != -1){
                                projectUrl = projectUrl.substring(0, projectUrl.indexOf(";", 0));
                        }
                </script>
        </head>
        <body>
                <fieldset>
                <legend>Registration Form</legend>
                <center>
                <form:form commandName="user" action="/SpringMVCMyBatisCRUDExample/app/registration/add" name="userForm">

                <form:hidden path="id"/>
                <table>
                        <tr><td colspan="2" align="left"><form:errors path="*" cssStyle="color : red;"/></td></tr>
                        <tr><td>Name : </td><td><form:input path="name" /></td></tr>
                        <tr><td>Standard : </td><td><form:input path="standard" /></td></tr>
                        <tr><td>Age : </td><td><form:input path="age" /></td></tr>
                        <tr><td>Sex : </td><td><form:select path="sex">
                                        <form:option value="Male"/>
                                        <form:option value="Female"/>
                        </form:select></td></tr>
                        <tr><td colspan="2"><input type="submit" value="Save Changes"/>
                        &nbsp;<input type="reset" name="newUser" value="New User" onclick="setAddForm();" disabled="disabled"/>
                        &nbsp;<input type="submit" name="deleteUser" value="Delete User" onclick="setDeleteForm();" disabled="disabled"/></td></tr>
                </table>
                </form:form>
                </center>
                </fieldset>
                <c:if test="${!empty users}">

                        <br />
                        <center>
                                <table width="90%">
                                        <tr style="background-color: gray;">
                                                <th>Name</th>
                                                <th>Standard</th>
                                                <th>Age</th>
                                                <th>Sex</th>
                                        </tr>
                                        <c:forEach items="${users}" var="user">
                                                <tr style="background-color: silver;" id="${user.id}" onclick="setUpdateForm('${user.id}');">
                                                        <td><c:out value="${user.name}"/></td>
                                                        <td><c:out value="${user.standard}"/></td>
                                                        <td><c:out value="${user.age}"/></td>
                                                        <td><c:out value="${user.sex}"/></td>
                                                </tr>
                                        </c:forEach>
                                </table>
                                </center>
                        <br />

                </c:if>
        </body>
</html></pre>
</div>
<div>

As you can see, the default action of the form is to add the form detail to database using add method of the controller. On click of “Delete User”, it will call a JavaScript function that will change the form url to delete the user. We have used<c:forEach/> jstl for showing all the users on the table and every row hasdeclaredon click even which will bring the table row data to form and also will change the form submit url to call update() method of controller.

Spring MVC configuration file

At last we will see the Spring MVC configuration that has been using to configure the controller and all other things. Following is the configuration file :

</div>
<div>
<pre><?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">

        <!-- Application Message Bundle -->
        <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
                <property name="basename" value="/WEB-INF/messages" />
                <property name="cacheSeconds" value="3000" />
        </bean>

        <!-- Scans the classpath of this application for @Components to deploy as beans -->
        <context:component-scan base-package="com.raistudies" />

        <!-- Configures the @Controller programming model -->
        <mvc:annotation-driven />

        <!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/WEB-INF/jsp/"/>
                <property name="suffix" value=".jsp"/>
        </bean>

        <import resource="jdbc-context.xml"/>
</beans></pre>
</div>
<div>

The configuration file includes themessages.properties as resource bundle and also includejdbc-context.xml configuration files which contains configuration for integration MyBatis 3 with Spring.

While running the example you will get the above screen as out put that will also show all the records present in database. Click on the “
Save Changes” button you will get following screen that will show you validation errors on the blank form values:

Spring MVC and MyBatis 3 Integration – User Form with validation errors 

Now fill the form with valid data and and click on the “Save Changes” button, it will bring the form data to bellow table.

That is all from this example. Hope that you have enjoyed the learning!!
:)

  1. Creating DAO class using MyBatis 3 that will help to perform CRUD operations on database.
  2. Setting Environment for integrating MyBatis 3 and Spring MVC 3 frameworks.
  3. Creating Spring MVC 3 controller for performing CRUD operation.

You can download the source code and war file from following links:

Source (Eclipse Project without jars) :
Download

War (With jars) :
Download


Reference:
Spring MVC 3 controller for performing CRUD operation using MyBatis(iBatis) 3 from our
JCG partner Rahul Mondal at the
Rai Studies blog.

Source : http://www.javacodegeeks.com/2012/05/spring-mvc-3-controller-for-mybatis.html