Wednesday, December 31, 2014

Inter servlet communication in Java

Major reasons to use inter servlet communication
  • Direct Servlet manipulation/handling: One servlet can access to other loaded servlets on the server and perform some task. One servlet obtains information about other servlets through ServletContext object.
  • getServlet() method returns the servlet of given name
    • public Servlet ServletContext.getServlet(String name) throws ServletException
  • Specified name can be servlet's registered name or class name
  • getServlet("file") returns different instance than getServlet("com.sun.server.webserver.FileServlet") because server maintains one servlet instance per name
  • getServlets() method return enumeration of all servlet objects loaded in current ServletContext.
  • Generally there are only one ServletContext object but for security or other reasons there can be many

Example

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
public class Loaded extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException{
    response.setContentType("text/html"); 
    PrintWriter out = response.getWriter(); 
    ServletContext context = getServletContext();
    Enumeration names = context.getServletNames();
    while (names.hasMoreElements()){
      String name=(String)names.nextElement();
      Servlet servlet =context.getServlet(name);
      out.println("Servlet name: "+name);
      out.println("Servlet class: "+ servlet.getClass().getName());
      out.println("Servlet info: "+ servlet.getServletInfo());
}}}

Servlet reuse

One servlet can reuse the abilities (public methods) of another servlet. There is challenge though for using methods of unloaded servlets.

Servlet collaboration

Collaboration is done through information sharing. Collaborating servlets can share data directly through method invocations. Servlets must know each other for collaboration. Collaboration can be done through following two methods

Collaboration using system property list

Java's system wide properties list found in java.lang.System class. This list holds standard system properties like java.version, path.separator and other application specific properties. The properties can be accessed by other servlets running on the same JVM. Property class is string based ie key and values are strings.
  • System.getProperties().put("key","value") is called to add or change a property
  • String value=System.getProperty("key") is used to access the value of key
  • System.getProperties().remove("key") is used to remove the property

Collaboration through a shared object

Shared objects can hold pool of shared information and make it available to other servlets when needed. System properties list is special case example of shared object. The shared object often incorporates business logic to manipulate the data. The business logic also protects data by defining mutators, accessors and other methods. Garbage collector might reclaim the shared object when it is not referenced by a loaded servlet. To keep garbage collector at bay, every servlet using a shared object should save reference to the object.

Database Connectivity with servlets

Every programmer needs to connect to database for storing and retrieving the information. In Java, database connection is made easy by Java Database Connectivity (JDBC) API.

  • Database connectivity is done through JDBC (Java Database Connectivity)
  • JDBC is well defined database independent database connectivity API
  • Middle tier i.e. stays between servlet and database

Example: Code implementing Phone book in Java through JDBC


import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
 public class DBPhoneLookup extends HttpServlet{
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ 
    //Define required variables
    Connection con = null;
    Statement stmt = null;
    RequestSet rs = null;
    response.setContentTyp("text/html");
    PrintWriter out = response.getWriter();

    try{
      //load and register oracle driver
      Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);

      //get a connection to the database
      Connection con = DriverManager.getConnection(jdbc:odbc:Access);

      //Create a statement object
      stmt = con.createStatement;

      //execute SQL query and geta a result set
      rs = stmt.executeQuery("select name, address from customer");

      //display result set
      out.println("<html><head><title>Employee phonebook</title></head><body><ul>");

      while(rs.next())
        out.println("<li>"+rs.getString("name")+", "+rs.getString("address"));
 
      out.println("</ul></body></html>");

    } catch(ClassNotFoundException e) {
      out.println("Couldn't load database driver: "+ e.getMessage());
    } catch(SQLException e) {
      out.println("SQL Exception: "+ e.getMessage());
    }

    finally {
      try{
        if (con !=null) con.close();
      } catch(SQLException e) {
      out.println("SQL Exception: "+ e.getMessage());
    }
}}

Session tracking with persistent cookies in Java

Cookies are used to store certain client information in client side. It is created by server, sent to browser, and browser manages cookies to identify itself to the server when re-connected.
  • Cookie is a bit of information sent by a web server to a browser
  • Browser stores cookie on client machine and later sends back to server each time it access page on that server
  • Generally used to identify client, list client's preferences and used for session tracking
  • Some browsers don't support or accept cookies
  • javax.servlet.http Cookie class is used for working with cookies.
  • Cookies can be created with Cookie() constructor with initial name and value
    • public Cookie(String name, String value)
  • Servlet can send a cookie to the client by passing a Cookie object to addCookie() method of HttpServletResponse
    • public void HttpServletResponse.addCookie(Cookie cookie)
  • Cookies are sent using HTTP headers so they should be added to response before any content is sent to the client
  • Multiple cookies can be added to a response
  • Browsers generally accept 20 cookies per site and 300 cookies per client and may limit cookie size to 4KB

Example: Set cookie with initial id field

//set cookie with initial id field
Cookie cookie=new Cookie("id","123"); 
 
//add cookie to the response object
response.addCookie(cookie); 
 
//retrieve cookie from the client
Cookie[] cookies = request.getCookies(); 
 
if(cookies!=null){
  for(int i=0;i<cookies.length;i++){
    String name=cookies[i].getName();
    String value=cookies[i].getValue();
}}

Some methods of cookies used for session tracking

  • Maximum expiry age in seconds; negative value specifies default and zero value specifies, cookie is deleted when browser exists
    • public void Cookie.setMaxAge(int expiry)
    • public int getMaxAge()
    • public void Cookie.setVersion(int v)
  • Return domain of the cookie, null if not defined
    • public String getDomain()
  • Set domain attribute to define which hosts the cookie should be presented to by the client ( eg .example.com)
    • public void Cookie.setDomain(String pattern)
  • Indicate the user agent that this cookie should only be sent via secure channel like HTTPS
    • public void Cookie.setPath(String uri)
  • Assign new value to cookie
    • public void Cookie.setValue(String newValue)
  • Return the value of cookie
    • public String getValue()

Example session tracking using persistent cookie. Implementing shopping cart in Java

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ShoppingCartViewerCookie extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response) 
   throws servletException, IOException{
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();

    //get the current sessionid if exists by searching the received cookies
    String sessionid=null;
    Cookie[] cookies = request.getCookies();

    if(cookies!=null){
      for(int i=0;i<cookies.length;i++){
        if(cookies[i].getName().equals("sessionid")){
          sessionid=cookies[i].getValue();
          break();
        }
      }
    }
 
    //set session id if it was not found and send it to client with response
    if(sessionid==null){
      sessionid=generateSessionId();
      Cookie c = new Cookie("sessionid",sessionid);
      response.addCookie(c); 
 
    //display information about shopping cart after setting sessionid
    out.println("<html><head><title>Shopping cart</title></head><body>");

    //cart items are associated with session id
    String items = getItemsFromCart(sessionid);
    out.println("<h1>You have following items in your shopping cart</h1>");

    if(items==null){
      out.println("No items");
    } else {
      out.println("<ul>");
      for(int i=0; i<items.length;i++)
        out.println("<li>"+ items[i] + "</li>");
      out.println("</ul>");
    }

    //Ask if client want more item or check out
    out.println("<form action=\"/servlet/ShoppingCart\" method="POST">");
    out.println("<input type=submit value=\"Add more items to cart\">");
    out.println("<input type=submit value=\"Check out\">");
    out.println("</form>");
}}

Session Tracking in HTTP Servlet Programming in Java

HTTP is stateless protocol. A web server can keep track of clients and distinguish them by using session. This helps in delivering customized services for each client. The server identifies each client with session tracking
  • Each client is associated with javax.servlet.http.HttpSession object
  • Any set of arbitrary java objects can be saved in session object
  • getSession() method is used to retrieve the current HttpSession object. This method is in request object.
    • public HttpSession HttpServletRequest.getSession() //create new if not exist
    • public HttpSession HttpServletRequest.getSession(boolean create)
    • This gets or creates new one if create argument is set and returns HttpSession object otherwise return null
  • putValue() method is used to add data to HttpSession object
    • public void putValue(String name, Object value)
  • getValue() method is used to retrieve data from the session object
    • public Object HttpSession.getValue(String name)
  • getValueNames() method is used to retrieve array of all name-value pairs bound to session
    • public String[] HttpSession.getValueNames()
  • removeValue() method removes values from the session
    • public void HttpSession.removeValue(Strin name)
  • All these methods throw throws java.lang.IllegalStateException

Example implementing hit counter using session tracking in Java

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SessionTracker extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws servletException, IOException{
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    //gets the current session object, create one if necessary (true)
    HttpSession session = request.getSession(true);
    //increment the hit count ofr this page. The value is saved
    //in this client's session under the name "tracker.count"
    Integer count = (Integer)session.getValue("tracker.count");
    If (count==null)
      count=new Integer(1);
    else
      count = new integer(count.intValue()+1);
    session.putValue("tracker.count",count);
    out.println("<html><head><title>Session tracker</title></head>");
    out.println("<body><h1>Session Tracking Demo</h1>");
    out.println("You visited this page "+ count + " times");
    out.println("<h2>Your Session Data</h2>");
    String[] names = session.getValueNames();
    for (int i=0;i<names.length;i++){
      out.println(names[i]+": "+session.getValue(names[i]+"<br>");
    }
    out.println("</body></html>");
}}

Servlet Life cycle in Java HTTPServlet

We generally start writing Java code with main() method. Servlets don't contain this method. Beginners are confused how this servlet runs. Before we start coding servlets, we need to know how it operates. What stages does it pass through. With this information, we can understand the inner working of servlets.
  • Servlets run inside servlet container, so creation and destruction of servlet is the responsibility of servlet container.
  • Servlet life cycle is defined by javax.servlet.Servlet interface, which defines how it is initialized, how it handles request and response, and how it is taken out of service
  • init() and destroy() methods are used by servlet container to do the task
  • life cycle can be understood by following flow
    • Servlet class
    • Instantiating and loading: servlet engine can instantiate more than one servlet instance
    • Initialization: (servlet config) init() method
    • Ready service method: A service method executes for each servlet interface
    • Destruction: destroy() method
    • Garbage collection: Server no longer has reference to the object

In servlet Life Cycle, the major stages are

  • Servlet Initialization: Servlet initialization is done by calling servlet’s constructor and init() method only once during servlet life cycle. Initialization is done automatically when needed or at startup if container is specifically told to load at startup. It is started automatically as soon as request is made e.g. opening database connection. It is loaded at startup if load-at-startup tag is set to nonzero.
  • Servlet Execution: No new instance of servlet is created at this stage. However, request and response objects are created, which are used to communicate with the one that is requesting. Servlet container forwards all the requests to servlet’s service() method. This service() method is executed every time request is made. The HttpServlet class breaks this service() method to more useful doGet(), doPost(), doPut(), doDelete(), doTrace(), doOptions() etc methods according to HTTP request. Only the required methods need to be overridden to carry out our task.
  • Servlet Destruction: When application is stopped or servlet container shuts down, the servlet is destroyed by calling destroy() method. This method frees the resources used by servlet.
  • Here, init() and destroy() methods are called only once during life cycle while service() method is called as many time as required after initialization.

Servlet showing life cycle in Hello World example

include java.io.*
include javax.servlet.*
include javax.servlet.http.*

public class HelloWorld extends HttpServlet {

    public String name = "Hello World"
    @Override
    public void init() throws ServletException{
        System.out.println("Method init() called");
    }
 
    //@Override is needed to inform compiler that method is overridden
    @Override
    public void destroy() {
        System.out.println("Method destroy() called");
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException,IOException {
        response.setContetnType("text/html");
        PrintWriter out=getWriter();
        out.println("<html><head><title>");
        out.println(name);
        out.println("</title></head>");
        out.println("<body><h1>Hello World</h1>You are welcome!</body></html>");    
    }
 
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {
         doGet(request, response)
    }
}

What is java servlet and how to write a servlet

Servlets are like regular java program but with peculiar characteristics. It is generally intended to run in web server and give web services to the clients. Servlets are made to handle the HTTP requests like GET and POST. These requests are handled by overriding the doGet() and doPost() methods in Service() method of javax.servlet.Servlet interface.
  • Do not have main() method; runs in servlet container on web server like tomcat
  • Implements javax.servlet.Servlet interface of J2EE
  • Implements http requests like get, post, put, delete etc by overriding doGet(), doPost() methods of HttpServlet class
  • doGet() and doPost() methods in servlet gets parameters from browser in HttpServletRequest and sets parameters of HttpServletResponse which can be used by JSP to display variables  and render html in User interface

get request —————>|———————— |               overrides
get response <————  | Servlet implements |<———>doGet()
                                         | Service() method    |
post request  ————> | of Servlet class        |<———>doPost()
post response <————|________________ |

Servlet Hello World Example

It is very easy to program servlet, we can program it only with the knowledge of which class to inherit and which methods to override.

include java.io.*
include javax.servlet.*
include javax.servlet.http.*
 
public class HelloWorld extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException,IOException {
        response.setContentType("text/html");
        PrintWriter out=getWriter();
        out.println("<html><head><title>Hello World</title></head>");
        out.println("<body><h1>Hello World</h1>You are welcome!</body></html>");    
}}

getWriter() method of the HTTPServletResponse class to set the output to response object. In the last two lines, HTML output is printed, so that browser receiving that can render proper HTML.

Two important interfaces included in servlet API

HttpServletRequest interface

When any request is made by client, the servlet container makes request object and passes to service() method of the servlet. This interface encapsulates functionality for a request object passed to HTTP servlet. Provides access to input stream and allows servlet to read data from clients like from forms. It contains following methods

public Cookie[] getCookies()
public String getQueryString()
public HttpSession getSession() //creates session if no established session
public HttpSession getSession(boolean create) //creates session if arg is set
public String getHeader(String name)
public String getParameter(String name)

HttpServetResponse interface

Encapsulates the functionality of response object returned to the client by the servlet. Provides access to output stream and allows servlet to send data to clients. It contains following methods to formulate response to client

public void addCookie(Cookie cookie);
public void sendError(int statusCode) throws IOException
public void sendError(int statusCode, String message) throws IOException
public PrintWriter getWriter() //Outputs character based output data
public ServletOutputStream getOutputStream() //outputs byte based binary data
public void sendRedirect(String location) throws IOException //temp redirect response

Thursday, May 22, 2014

Hibernate Table Deleted After Stopping and Starting New Session in Java Application

When I was new to Hibernate and JPA, I used Hibernate to create table from Entity definition. But I was annoyed to find out it was always deleted after the program was closed and started again. But the solution was very simple. I had to open the persistence.xml file and edit some valued. When I opened the persistence.xml file the file contents was like following: The persistence.xml file is generally located inside src/main/resources/META-INF/ folder.
<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
   <provider>org.hibernate.ejb.HibernatePersistence</provider>
   <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect">
      <property name="hibernate.hbm2ddl.auto" value="create">
      <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy">
      <property name="hibernate.connection.charSet" value="UTF-8">
   </property></property></property></property></properties>
</persistence-unit>

I had to edit the property
<property name="hibernate.hbm2ddl.auto" value="create"></property>

The community documentation states that hibernate.hbm2ddl.auto Automatically validates or exports schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly.
There are few options for this property and they are: validate | update | create | create-drop

  • validate: validates the schema, it makes no changes to the database. 
  • update: update the schema. 
  • create: creates the schema, it destroys the current data before creating the new table, but does not destroy after the end of the session. 
  • create-drop: drop the schema at the end of the session and create it at the beginning of session.

So I changed the value to update and the value in database remained intact in new sessions.
<property name="hibernate.hbm2ddl.auto" value="update"></property>

Create own ID column auto managed by JPA

By default, JPA uses Id column, but I want to create my own id column named userid for my user table. I am always confused with Id column in multiple tables so I append entity name before id in order to know which one I am referring. For an example, for user table I use userid, for customer, I use customerid and so on.

For that, I created a new id column for JPA entity and annotated it with @Id.

 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 @Column(name = "user_id")
 private Integer userid;


But it didn't work for me. After searching the web for some time, I found out that I should use full package name for ID. in the place of @Id, I had to use @javax.persistence.Id The resulting code was this

 @javax.persistence.Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 @Column(name = "user_id")
 private Integer userid;

Now the code works fine.

Wednesday, April 30, 2014

Setting up Spring MVC web application with Hibernate and Spring Security for beginners step by step

This lecture was provided by calstatela.edu website. I have listed all the steps provided in spring web MVC with Hibernate and Spring security in one single page with appropriate code where necessary.

First step: Create an Maven Application


Create Maven web application in Eclipse using the maven-archetype-webapp archetype and do the following:

1. Change web.xml to the following:
<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 
  version="3.0" id="springmvc">

 

  <display-name>Spring MVC Example</display-name>

 
  <welcome-file-list>
 
    <welcome-file>index.jsp</welcome-file>
 
  </welcome-file-list
>

</web-app>

This change basically says that our project requires an application server that supports the Servlet 3.0 Specification.
2. Add the following to pom.xml (right after <finalName>):
<plugins>
 
  <plugin>
 
    <groupId>org.apache.maven.plugins</groupId>
 
    <artifactId>maven-compiler-plugin</artifactId>
 
    <version>3.1</version>
 
    <configuration>
 
      <source>1.7</source>
 
      <target>1.7</target>
 
    </configuration>
 
  </plugin>

</plugins>

This change says that the project requires JDK 1.7 (or above) to compile, and the compiled class files are compatible with JVM 1.7.

3. Due to some bug in Eclipse Kepler Release, Eclipse can no longer change project facets based on changes to web.xml and pom.xml, so we have to do it manually:
  • Close Eclipse.
  • Use a text editor to open the file .setting/org.eclipse.wst.common.project.facet.core.xml under the project folder (i.e. <workspace>/<project>), and change the version of java and jst.web to 1.7 and 3.0 respectively:
    <installed facet="java" version="1.7" />

    <installed facet="jst.web" version="3.0 />
    
    Start Eclipse, Right click on the project and select Maven -> Update Project...

4. Remove the junit dependency (we'll use TestNG instead), the add the following dependencies to pom.xml:
  • javax.servlet:javax.servlet-api:3.0.1 (set the scope of the dependency to provided)
  • javax.servlet:jstl:1.2

  • Maven code for including these dependencies
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.0.1%lt;/version>
      <scope>provided%lt;/scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    
This allows us to use classes like HttpServletRequest and HttpServletResponse in our Java code, and use JSTL in the JSPs.
5. Add a folder src/main/java. This is where the Java code would go.
6. Right click on the project and select Maven -> Update Project...


Step 2: Convert this project to Spring web MVC


Make the following changes to the Maven web application we created in the previous step:
1. Add the dependency org.springframework:spring-webmvc:3.2.3.RELEASE
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>3.2.3.RELEASE</version>
  <!-- Current spring version 4.0.3 is not currently compatible with spring security so we use spring 3.2.3 -->
</dependency>

At the time of writing the latest Spring Framework release is 4.0.3. The reason we use 3.2.3 instead is that later we'll add Spring Security which depends on Spring 3.2.3. If you don't plan to use Spring Security, feel free to use the latest Spring Framework; otherwise be aware that Spring Security usually lags a little behind the main framework release.
2. Add the following to web.xml:
<servlet>
 
  <servlet-name>springmvc</servlet-name>

  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 
</servlet>

 
<servlet-mapping>
 
  <servlet-name>springmvc</servlet-name>
 
  <url-pattern>*.html</url-pattern>
 
</servlet-mapping>

The DispatcherServlet is loaded when the web application is started (notice the <load-on-startup>), and it is responsible for initializing the Spring servlet context, i.e. creating all the beans specified in a bean configuration file. The default name for the bean configuration file is /WEB-INF/<dispatcher-servlet-name>-servlet.xml. In our case, the name of the DispatcherServlet is springmvc (notice the <servlet-name>) so the bean configuration file is /WEB-INF/springmvc-servlet.xml. During operation DispatcherServlet also serves as the front controller that dispatches requests to the proper controller based on controller URL mapping.
3. Create the Spring bean configuration file /WEB-INF/springmvc-servlet.xml as follows:
<?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:mvc="http://www.springframework.org/schema/mvc"
 
  xmlns:context="http://www.springframework.org/schema/context"

  xsi:schemaLocation="http://www.springframework.org/schema/beans
 
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 
    http://www.springframework.org/schema/mvc

    http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
  http://www.springframework.org/schema/context
 
    http://www.springframework.org/schema/context/spring-context-3.2.xsd">

 
  <mvc:annotation-driven />

 

  <context:component-scan base-package="springmvc.web" />

 

  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
 
    <property name="prefix" value="/WEB-INF/jsp/" />
 
    <property name="suffix" value=".jsp" />
 
  </bean>


</beans>

<mvc:annotation-driven/> enables request dispatching to @Controllers among some other things. <context:component-scan> finds all the annotated beans in springmvc.web and its sub-packages. The InternalResourceViewResolver maps a view name to a JSP file. It has two properties: prefix and suffix, so a view name like "home" would be mapped to a JSP file /WEB-INF/jsp/home.jsp.
And this is pretty much it - your web application is now a Spring MVC application. You can create a controller and a view like the following:
src/main/java/springmvc/web/controller/HomeController.java
package springmvc.web.controller;

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

@Controller
public class HomeController {
  @RequestMapping("/home.html")
  public String index(){
    return "home";
  }
}

src/main/webapp/WEB-INF/jsp/home.jsp
<html>
  <head><title>Spring MVC Example</title></head>
  <body>
    Welcome to Spring MVC.
  </body>
</html>

And after that you can run the project and check if it works at the URL http://localhost:8080/springmvc/home.html .


Step 3: Add Hibernate

Hibernate
There are many different ways to configure Hibernate with Spring - first of all you can use either JPA or Hibernate Session, and then you have various choices like using hibernate.cfg.xml or not using one, specifying database information in Spring or in Hibernate, creating a data source in Spring or getting one from JNDI, and so on. Here I'll describe the way that I think is the best and the simplest.
Make the following changes to the Spring MVC application we created in the previous step:
1. Add the following dependencies:
  • org.hibernate:hibernate-entitymanager:4.2.11.Final
  • org.springframework:spring-orm
  • org.apache.tomcat:tomcat-jdbc
  • org.postgresql:postgresql
Maven code for including these dependencies:
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-entitymanager</artifactId>
  <version>4.2.11.Final</version>
</dependency>
Likewise include all dependencies.
tomcat-jdbc is for database connection pooling under Tomcat. postgresql is the database driver.
Note that if we don't specify the version of a dependency, it means the latest release version is used (i.e. not alpha, beta, RC etc.), with the exception of Spring related dependencies, for which you should choose the same version as spring-webmvc used in the previous step.
2. Add a file src/main/resources/META-INF/persistence.xml as follows:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
 
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
 
  version="2.0">

  <persistence-unit name="springmvc">
 
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
 
    <properties>
 
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
 
      <property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
 
    </properties>

  </persistence-unit>


</persistence>
This file provides the information about the JPA Entity Manager provider.
3. Add the following to web.xml:
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 
</listener>
<filter>
 <filter-name>jpaFilter</filter-name> <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> </filter>
<filter-mapping> <filter-name>jpaFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

The ContextLoaderListener will load another Spring bean configuration file, and by default the file is /WEB-INF/applicationContext.xml. This bean configuration file is not absolutely necessary for this step - we could put all the Hibernate/database beans in springmvc-servlet.xml, but this file is required later when we add security to the application, and it is customary to put beans that are not related to the web tier in applicationContext.xml as oppose to <dispatcher-servlet-name>-servlet.xml, which is sometimes referred to as the servlet context.
The jpaFilter keeps the entity manager open until after the view is rendered; without it Hibernate won't be able to load lazy collections in JSP.
4. Create a file /WEB-INF/applicationContext.xml as follows:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 
  xmlns:context="http://www.springframework.org/schema/context"
 
  xmlns:tx="http://www.springframework.org/schema/tx"
 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 
  xsi:schemaLocation="http://www.springframework.org/schema/beans
 
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 
    http://www.springframework.org/schema/context
 
    http://www.springframework.org/schema/context/spring-context-3.2.xsd
 
    http://www.springframework.org/schema/tx
 
    http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

 
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
 
  <property name="driverClassName" value="org.postgresql.Driver" />
 
  <property name="url" value="jdbc:postgresql://localhost:5432/springmvc" />
 
  <property name="username" value="cysun" />
 
  <property name="password" value="abcd" />
 
  <property name="initialSize" value="1" />
 
</bean>

 
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
 
  <property name="persistenceUnitName" value="springmvc" />
 
  <property name="dataSource" ref="dataSource" />
 
</bean>

 
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
 
  <property name="entityManagerFactory" ref="entityManagerFactory" />
 
</bean>

 
  <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

 
<context:annotation-config />

 
  <tx:annotation-driven />

 
  <context:component-scan base-package="springmvc.model" />


</beans>

It adds four beans: a data source, an entity manager factory, a transaction manager, and an exception translator that translates various SQL/database exceptions into a Spring exception. <context:annotation-config> enables annotations like @Autowired and @PersistenceContext (which is like an @Autowired specifically for entity manager), <tx:annotation-driven> enables annotations like @Transactional, and <context:component-scan> looks for beans under the package springmvc.model and its sub-packages (presumably that's where your DAO classes are located).
And that is it. Now the application is a web application with both Spring and Hibernate. Here is some code you can use for testing:
src/main/scripts/springmvc-create.sql
create table users (
  id integer primary key,
  username varchar(255) unique not null,
  password varchar(255) not null,
  enabled boolean not null default 't'
);

insert into users values (1, 'admin', '1234', 't');
insert into users values (2, 'cysun', 'abcd', 't');

create table authorities (
  username varchar(255) not null references users(username),
  authority varchar(255)
);

insert into authorities values('admin', 'ROLE_ADMIN');
insert into authorities values('cysun', 'ROLE_USER');

src/main/scripts/springmvc-drop.sql
drop table authorities;
drop table users;


src/main/java/springmvc/model/User.java
package springmvc.model;

import javax.persistence.Entity; 
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
 
@Entity
@Table(name = "users")
public class User {
  @Id
  @GeneratedValue
  private Integer id;
  private String username;
  private String password;
  private boolean enabled = true;

  public User(){
  }
  public Integer getId(){
    return id;
  }
  public void setId( Integer id ){
    this.id = id;
  }
  public String getUsername(){
    return username;
  }
  public void setUsername( String username ){
    this.username = username;
  }
  public String getPassword(){
    return password;
  }
  public void setPassword( String password ){
    this.password = password;
  }
  public boolean isEnabled(){
    return enabled;
  }
  public void setEnabled( boolean enabled ){
    this.enabled = enabled;
  }
}

src/main/java/springmvc/model/dao/UserDao.java
package springmvc.model.dao;

import java.util.List; 
import springmvc.model.User;
 
public interface UserDao {
  User getUser( Integer id );
  List<User> getUsers();
}

src/main/java/springmvc/model/dao/jpa/UserDaoImpl.java
package springmvc.model.dao.jpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import springmvc.model.User;
import springmvc.model.dao.UserDao;
 
@Repository
public class UserDaoImpl implements UserDao {
  @PersistenceContext
  private EntityManager entityManager;

  @Override
  public User getUser( Integer id ){
    return entityManager.find( User.class, id );
  }
 
  @Override
  public List<User> getUsers(){
    return entityManager.createQuery( "from User order by id", User.class ).getResultList();
  }
}


src/main/java/springmvc/web/controller/UserController.java
package springmvc.web.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import springmvc.model.dao.UserDao;

@Controller
public class UserController {
  @Autowired
  private UserDao userDao;

  @RequestMapping("/users.html")
  public String users( ModelMap models ){
    models.put( "users", userDao.getUsers() );
    return "users";
  }
}


src/main/webapp/WEB-INF/jsp/users.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>\
<html>
  <head><title>Users</title></head> 
  <body>
  <table>
      <tr><th>ID</th><th>Username</th><th>Enabled</th></tr>
      <c:forEach items="${users}" var="user">
        <tr>
         <td>${user.id}</td>
         <td>${user.username}</td>
         <td>${user.enabled}</td>
         </tr>
      </c:forEach>
    </table>
  </body>
</html>


Step 4: Testing


Testing
There are two popular Java testing frameworks: JUnit and TestNG. There was a time when TestNG was considered technically superior, but these days these two are pretty much the same. In this section we will describe how to use TestNG to test database access.
1. Add the following dependencies:
  • org.testng:testng
  • org.springframework:spring-test
and set the scope of both dependencies to test. The maven code for this will be

 
2. Create the following folders:
  • src/test
  • src/test/java
  • src/test/resources
then right click on the project and select Maven -> Update Project.... The testing code will be placed under src/test/java, which mirrors the structure of src/main/java, and the resource files used during testing will be placed under src/test/resources.
3. Copy src/main/webapp/WEB-INF/applicationContext.xml to src/test/resources. This bean configuration file will be used by the testing code to initialize the Spring framework and create beans for data sources, entity manager, and so on.
4. Create a test class as follows and place it under src/test/java/springmvc/model/dao:
package springmvc.model.dao;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests;
import org.testng.annotations.Test;
 
@Test(groups = "UserDaoTest")
@ContextConfiguration(locations = "classpath:applicationContext.xml")

public class UserDaoTest extends AbstractTransactionalTestNGSpringContextTests {
  @Autowired

  UserDao userDao;

  @Test

  public void getUser()
{

    assert userDao.getUser( 1 ).getUsername().equalsIgnoreCase( "admin" );

  }

  @Test

  public void getUsers()
{
    assert userDao.getUsers().size() == 2;

  }
}
In Eclipse, right click the class and select Run As -> TestNG Test. If you have created the database using springmvc-create.sql as described in the previous step, both tests should pass.


Step 5: Spring Security

Spring Security
Make the following changes to the Spring and Hibernate application we created in the previous step:
1. Add the following dependencies to pom.xml:
  • org.springframework.security:spring-security-taglibs
  • org.springframework.security:spring-security-config
2. Add the following to web.xml:
<filter>
  <filter-name>springSecurityFilterChain</filter-name>

  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 
</filter>


<filter-mapping>

  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

The DelegatingFilterProxy is the entry point of Spring Security, which utilizes a number of handler interceptors (Spring's equivalent of servlet filters) and method interceptors configured in applicationContext.xml to implement security. Note that the URL pattern /* ensures that all requests will pass through Spring Security.
3. Add the security namespace to applicationContext.xml so the beginning of the file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
  
<beans xmlns="http://www.springframework.org/schema/beans"
 
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:security="http://www.springframework.org/schema/security"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.1.xsd

    http://www.springframework.org/schema/tx

    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd

    http://www.springframework.org/schema/security

   http://www.springframework.org/schema/security/spring-security-3.1.xsd">

And then add the following to applicationContext.xml:
<security:authentication-manager>
<security:authentication-provider>

   <security:jdbc-user-service data-source-ref="dataSource" />
  </security:authentication-provider>
</security:authentication-manager>
<security:http auto-config="true" use-expressions="true">
 <security:intercept-url pattern="/users.html" access="hasRole('ROLE_ADMIN')" />

</security:http>
Authentication is done using the users and authorities table we created in the Hibernate step. Here we simply let <jdbc-user-service> reference the data source and Spring Security will take care of the rest. The <http> element sets up a number of Spring Security filters for a web application environment, and <intercept-url> can be used to control access to certain URL patterns based on the roles of a user. And this is it. Your web application now have some basic security measures in place.