Annotated Dependency Injection / Inversion of Control (DI / IoC) in Spring 3 Web MVC using Netbeans

This tutorial will detail how to insert services and components (Dependency Injection) into a Spring 3 Web MVC Netbeans application.

The process used is Dependency Injection (DI) or Inverse of Control (IoC) whereby Spring will instantiate (or inject) certain components at runtime rather than at having them initiated at compile time.  This provides a highly decoupled design which facilitates ‘change’ more easily. Importantly, it also makes comprehensive Unit Testing (with Mock Objects) much easier to achieve. IoC is a conventional design pattern.

This tutorial is quite comprehensive in that it will simulate CRUD operations on ‘Person’ objects. For simplicity, it does not used a database, data will be put stored in the ‘HttpSession’ object instead.

The code is available for download at the bottom of this page.

As per this ‘hello world’ spring tutorial using Netbeans, create a web project, do not include the Spring framework. For this example, I’ve called the project ‘HelloSpringDI’ and used Apache Tomcat 7 as the application server.

  • Delete ‘index.jsp’ which was created automatically.
  • Create a new folder called ‘jsp’ under WEB-INF.
  • Create a new folder under ‘jsp’ called ‘person’
  • Create three new .jsp files in the ‘WEB-INF/jsp/person’ folder, namely, ‘list.jsp’, ‘edit,jsp’ and ‘delete.jsp’  (The contents will be provided in a moment)
  • Create a ‘web.xml’ file in the ‘WEB-INF’ folder.
  • Create another xml file in the ‘WEB-INF’ folder called ‘dispatcher-servlet.xml’.
  • Create a new Source File package namely, com.outbottle.springdi.controllers
  • In that package, create a new class called ‘PersonController’ (just a normal .java file for now)
  • Right click the project’s ‘Libraries’ folder and choose ‘Add Library’.  Add the following Libraries: JSTL 1.1, Spring Framework 3.0.6 RELEASE, Spring Web MVC 3.0.6 RELEASE. (Normally it’s best to download the latest versions of the spring distribution rather than using the libraries provided by Netbeans, but for simplicity we’ll use the existing spring libraries for this tutorial).

The project should now look like this:

 

Spring 3 Web MVC IoC Inversion of Control DI Dependency Injection project setup

Here’s what should be in each file:

web.xml

 Note: The <welcome-file> is not ‘index’ it’s actually ‘person/list’. This equates to /WEB_INF/jsp/person/list.jsp as per the ‘jspViewResolver’ below in ‘dispatcher-servlet.xml’. In <servlet-mapping> note the second <url-pattern> /person/list. This is necessary to make the <welcome-file> work.

dispatcher-servlet.xml

 Note: <context:component-scan base-package is com.outbottle meaning that Spring should check for annotations in this package (recursively checking sub folders). <mvc:annotation-driven /> is necessary when using annotations in Spring 3. Without it, strange errors will occur. The ‘jspViewResolver’ is self evident when looking at the <welcome-file> in ‘web.xml’ above. This view resolver bean will prefix /WEB-INF/jsp and append .jsp onto the URL request. I.e. /person/list becomes /WEB-INF/jsp/person/list.jsp

PersonController.java

Now it’s all pulled together. It’s clear that /person/ is in each URL where we’ll be dealing with ‘Person’ objects (to be created in a moment).

Now, update each JSP with some identifying text i.e. delete, edit, and list

Add a link to /person/create in list.jsp

list.jsp

Now run the application to verify it’s all working. list.jsp will be the default page displayed. The link to ‘/person/create’ will invoke the controller method ‘create(…)’ thus revealing ‘edit.jsp’ (We’ll be using edit.jsp to edit and create to avoid code duplication).


As we’re using the HttpSession to store the data it’s necessary to provide global access to it.

Create a class called Util in com.outbottle.springdi.util

Util.java

Add a servlet filter to set the session object by creating a class called SessionFilter in com.outbottle.springdi.filters. More on Filters in this blog.

SessionFilter.java

Update web.xml with the following filter elements

 

Now create a ‘Person’ class in package com.outbottle.springdi.model.entities:

Person.java

 

We’re getting to the dependency injection (DI) but, first we need to create the various components that would typically be inserted via DI

Create a new class called ‘AbstractDao’ in com.outbottle.springdi.model.dao

AbstractDao.java

Create a sub class of AbstractDao called ‘PersonDao’ in com.outbottle.springdi.model.dao

PersonDao.java

Note: – The important thing here is the annotation

The value must match the member variable name where it will be inserted.

 

Create a new interface called ‘PersonService’ in package com.outbottle.springdi.model.service

PersonService.java 

 

In the same package, create a concrete class implementing PersonService.java. Call it PersonServiceImpl.java

PersonServiceImpl.java 

Note: – The annotation @AutoWired will tell spring to instantiate member variable ‘personDao’ with the ‘repository’ named “personDao”. I.e. the @Repository(“personDao”) in PersonDao.java matches this.

In addition, PersonService.java is annotated as a service called “personService”. In our PersonController.java,  a member variable called ‘personService’ will now be added to the class. Spring get’s the idea and will instantiate the member variable with PersonServiceImpl.

PersonController.java (updated)

 Note: The annotation @AutoWired will tell spring to instantiate member variable ‘personService’ with the ‘service’ named “personService”. I.e. the @Service(“personService”) in PersonServiceImpl.java matches this.

The edit and delete methods (of type RequestMethod.GET) are setup to receive the Person ID as a variable appended to URL. For more on this friendly URL capability please see my blog specifically on it.

@ModelAttribute causes a Person object to be populated and passed in from the HTML form. Hence methods with @ModelAttribute are of type RequestMethod.POST

Everything put (or map.addAttribute(“”, object)) into the ModelMap is available on the jsp/html side as will now be demonstrated.

The context path is being passed to the view in order to ensure correct links. Otherwise, relative links will become invalid as edit.jsp is used in two different contexts.

Finally, let’s add the code to the jsp files:

list.jsp

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

<%@page contentType=”text/html” pageEncoding=”UTF-8″%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<title>JSP Page</title>
<style type=”text/css”>
table {
border-collapse: collapse;
}
th, td {
padding:5px;
border:1px solid #ccc;
}
</style>
</head>
<body>
<h3>List!</h3>
<c:if test=”${empty personList}”>
<p>No People!</p>
<p><a href=”<%=request.getContextPath()%>/person/create”>Create Person</a></p>
</c:if>
<c:if test=”${!empty personList}”>
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Age</th>
<th colspan=”2″><a href=”<%=request.getContextPath()%>/person/create”>Create Person</a></th>
</tr>
<c:forEach items=”${personList}” var=”person”>
<tr>
<td>${person.id}</td>
<td>${person.name}</td>
<td>${person.age}</td>
<td><a href=”<%=request.getContextPath()%>/person/edit/${person.id}”>Edit</a></td>
<td><a href=”<%=request.getContextPath()%>/person/delete/${person.id}”>Delete</a></td>
</tr>
</c:forEach>
</table>
</c:if>
</body>
</html>

edit.jsp

<%@ taglib uri=”http://java.sun.com/jsp/jstl/core” prefix=”c” %>
<%@ taglib prefix=”form” uri=”http://www.springframework.org/tags/form” %>

<%@page contentType=”text/html” pageEncoding=”UTF-8″%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<title>JSP Page</title>
</head>
<body>
<c:if test=”${person.id == null}”>
<h3>Create!</h3>
</c:if>
<c:if test=”${person.id != null}”>
<h3>Edit!</h3>
</c:if>
<form:form commandName=”person” method=”POST” action=”{cp}/person/edit”>
<form:hidden path=”id” />

<label for=”nameId”>Name</label>
<form:input path=”name” id=”nameId” ></form:input>

<label for=”ageId”>Age</label>
<form:input path=”age” id=”ageId”></form:input>

<input type=”submit” name=”submit” value=”OK” />
</form:form>
</body>
</html>

delete.jsp

<%@ taglib uri=”http://java.sun.com/jsp/jstl/core” prefix=”c” %>
<%@ taglib prefix=”form” uri=”http://www.springframework.org/tags/form” %>

<%@page contentType=”text/html” pageEncoding=”UTF-8″%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<title>JSP Page</title>
</head>
<body>
<h3>Delete!</h3>
<form:form commandName=”person” method=”POST” action=”${cp}/person/delete”>
<p>
Are you sure you want to delete <strong>${person.name}</strong>?
</p>
<form:hidden path=”id” />
<input type=”submit” name=”submit” value=”Delete” />
</form:form>
</body>
</html>

And that’s pretty much it.

Some points of Note:

  1. The whole purpose of IoC or DI is to make unit testing easier to achieve because dependent “Mock” objects can be inserted in place of the normal implementations. In addition, change is facilitated easier given that a service or DAO can be replaced with a new implementation with minimal impact on the surrounding code.
  2. In this example, the service methods Create, Update, Delete seem to be potentially repetitive in a larger application. In an implementation that uses Hibernate or JPA Persistence this doesn’t have to be the case, a more generic DAO object will eliminate the need for this. This code demonstrates DI and IoC rather than good DAO design practices. (See my other blog for a more complete example that uses Hibernate persistence with Spring 3 Web MVC)
  3. From the above two points, it’s evident that each service or component that’s to be injected by Spring should implement an interface (or extend a generic class).

Anyway, here is the complete Netbeans project for download.

 

Hope this is useful, all comments welcome. Thanks

 

25 Comments

  • Pingback: film
  • hi i got an error 404 . i created all 3 jsps in person folder and just run the project but it didnt get into person folder (only acces /HelloSpringDI-2/WEB-INF/jsp/list.jsp ) . i used all exact code on ur site . im lil bit confused as this image ( http://outbottle.com/wp-content/uploads/2012/05/spring_di_proj.png )which does not shows any person folder and u said put all 3 jsps in to person folder in the jsp folder. please correct and let me know . your site is really helpful and thank you very much for your hard work. keep it up your good work.

    • Hi Laksh

      Good catch, and thank you for pointing it out. The image was incorrect. I’ve now corrected it. The image now shows ‘WEB-INF/jsp/person’

      I’m sorry to hear you’re having trouble. I think you should download the project from the link above (http://outbottle.com/wp-content/uploads/2012/05/HelloSpringDI.zip). This project is working correctly. It will run correctly without any configuration or additions. Examination of this should help solve your problems.

      Let me know if problems still persist and I will try to help.

      Thanks

      • Hey there, I just wanted to point out that I was having the same issue as Laksh and in downloading the source code I did find other mistakes that was still lingering in the above code. In the PersonController above it is returning “/list”, “/create”, and “/delete” for the three public functions. However in the downloaded source code it was returning “/person/list”, “/person/create”, and “/person/delete”.

        After updating my code to that it loaded right up. BTW i did not finish the tutorial before writing this so I am sorry if it was added further down the tutorial.

        • Yep, there are two PersonControllers above. The first is a milestone. The second is updated as you describe. I can see how it may be a little confusing if simply looking for quick answers (as most people including myself do all the time). This tutorial goes into detail hence the two PersonControllers above.

          Thanks for taking the time to share, I’m sure it will help others.

  • Hi, Thanks for another great tutorial. I am using Glassfish Server and needed to delete the entry / in the web.xml file to get this to work from Netbeans Run or Debug.

  • great tutorial. very well explained.

    My question is: how can i delete a particular row just by one click?
    i mean, i dont want to be redirected to delete.jsp page.
    the delete operation should be done there in list.jsp page by delete button(submit button instead of href).

    so, how to give control to the delete button and how will we write the controller for that?

    • Hi Soumya

      You would either have to use some JavaScript tricks or put a form (similar to the delete form) in place of each ‘delete’ link. There are several ways to do it really.

      Feel perfectly free to post here again if you are having specific problems or need further assistance.

      Thanks

    • You might of already figured this out but did you try changing the how the delete link posts to the controller? than modify the service so that you can delete a person by their id?

  • I am glad to have found this site.

    When deleting an entry I am redirected to a page not found error. I am finding this error in my IDE:

    [PageNotFound] No mapping found for HTTP request with URI [/HelloSpringDIWeb/person/delete}] in DispatcherServlet with name ‘dispatcher’

    I reviewed PersonController and as per the tutorial I have the proper code. I placed a break point on it and it is never reached.

    Here is the controller snippet

    @RequestMapping(value=”/delete”, method=RequestMethod.POST)
    public String delete(@ModelAttribute Person person){
    personService.delete(person);
    return “redirect:/person/list”;
    }

    Here is the delete.jsp snippet

    Are you sure you want to delete ${person.name}?

    Also If I wee to add a Cancel button to this form – how could it be done so that it redirects to the /person/list page? I know how to do it using an url. But not with the

      • I think you’ve got a typo in the delete form:

        <form:form action="{cp}/person/delete}" commandname="person" method="POST">

        should be

        <form:form action="${cp}/person/delete" commandname="person" method="POST">

        note the } at the end of the action url.

        If that’s it, try not to scream too loud or hit anything 😉

        • okay now you mention it – arg!!! Thanks! That also corrects the issue I had with my cancel button.

          Now this might be a beginner question but can multiple buttons appear inside the tags? or does each button need to be inside it own set of tags?

          Primarily if one is trying to Cancel/Ignore the delete operation, they can return to the list page without using the browser’s back button. I currently have each button inside a separate tags working but is this really the optimal way of completing the process.

          • The separate form tags is perfectly ok. I’d probably favour that option. Here are a few other options for consideration though.

            1.
            <a href="{cp}/person/list'">Cancel or Back</a>
            or

            2.
            <button onclick="javascript:window.location = '${cp}/person/list'">Cancel or Back</button>
            or

            3. (uses jQuery to apply an event handler to the button)
            <button id="cancel">Cancel or Back</button>

            <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js&quot; ></script>

            <script type="text/javascript">

            $(document).ready(function(){

            $('#cancelButton').click(function(){

            window.location = '${cp}/person/list';

            return false;

            });

            });

            </script>
            or

            4.
            <form …. >

            <button name="cancel" value="go to A" >A</button>

            <button name="cancel" value="go to B" >B</button>

            </form>

            You can check the value of the cancel parameter in the @Controller and determine where to go based on the value

            Only the value of the button pressed will be in the request

            (<button>'s do submit the form)