RSS

Spring MVC basic example with Maven

17 sep

springsourcelogo

In the following post we are going to talk about the Spring MVC project. But before that I have been thinking about writing some other posts about the Spring framework. I’m going to talk about some SpringSource projects such as Spring MVC, Spring Web Flow, Spring Security (O Auth) or Spring Faces to name a few. Moreover I’m planning to start writing about continuous integration and testing with (Hudson / Jenkins, Sonar, Cobertura, Selenium, Checkstyles, PMD, …). I’d also like write about Cloud Computing , as a novice developer in this particular subject, analyzing some frameworks and tools such as the Google App Engine (GAE) or Micro Cloud Foundry. But there is much left to all I have just mentioned so …. it is time to start with Spring MVC.

Introduction to Spring MVC.

Spring MVC is a SpringSource project that allows us to use the MVC design pattern in an easy way within our own applications that are developed using Spring. In the following image we can see the big picture of how it works Spring MVC.

SpringMVCLifeCycle

If we have previously developed web application projects we noticed that in Spring MVC our DispatcherServlet works under the front controller design pattern. The front controller desing pattern gives us a unique entry point to our web requests. So every request that is sent to our application is going to be intercepted by the same Servlet, in the case of Spring MVC, our server is called DispatcherServlet. This particular servlet manages the whole logic within our JEE application.

The basic flow in a Spring MVC application is as follows:

  • The request is received by our DispatcherServlet (1)
  • The DispatcherServlet will look up for a controller which copes the current request. For that end, our DispatcherServlet will need to find the appropiate handler to our request. This process will be taken within the HandlerMapping phase (2).
  • Once the Controller has been found, our DispatcherServlet will forward the management to that Controller(3). Our controller will manage the bussiness logic within our JEE application, i.e., here is where we are going to access to our service layer. The controller will response to the Dispatcher an object that belongs to the ModelAndView class (4). What does this mean?. In a nutshell, Model will be the returned object from the service layer and View is the view name where we want to include the information contained in the Model object.
  • Once the ModelAndView has been dispatched to the DispatcherServlet from the specified Controller, this DispatcherServlet will asociate the view name sent by the Controller with the specified view (a jsp, jsf, xhtml page …). You can see this process in the image below tagged as ViewResolver (4).
  • After the view had been resolved, our DispatcherServlet will pass our Model object to the concrete view View (5).

In the HandlerMapping, Controller and ViewResolver section we can head our DispatcherServlet to the strategy we want to use. Here, it is a very interesting post (Spanish) written by Alex Fuentes where it is explained how the handler mapping is taking.

Spring MVC with Maven

Why do I use GitHub?.

Now, we are going to explain the Java code and the configuration files to start with Spring MVC. As always, our projects will be management with Maven (2.2.1). As something new I’m gonna upload the project to my GitHub repository, so that you can have access to it en the following url:

git@github.com:IvanFernandez/hop2croftRepository.git

If you don’t know Git yet, you can take a look at the next posts:

The reasons why I upload my Java code to GitHub are in first place that it helps following the post to have all the code available and test it if we want. Besides that, I don’t like when you are reading some post and the imports package section isn’t included or I miss some sections. As I have uploaded the whole project to GitHub there is no need to write a post including the import section or every method in your java class, but at the same time people can download the source code and inspect it. Finally you can fork the project in GitHub and add some new improvements to the code.

Code explanation.

First of all take a look at the image below that shows the package explorer view in Eclipse.
PackageExplorerSpringMVC
As we can see in the previous image our project has the Maven folder structure METER LINK, i.e.:

Folder src/main/java

Here we find our java classes. We have four different package:

  • Controller. related to our controllers. In our project we are gonna need two specified controllers. CarController will be called when we request the car.html page and CarFormController for the carForm.html page.
  • Domain. our domain classes. We need a POJO that code a car entity called, Car.java. We have already seen in other posts the required services to create, modify or delete a car in our database.
  • Exception. In this package we have to include those classes that implement the exceptions our java code could throw.
  • Interceptor. Here, we find our Spring MVC interceptors. We can use interceptors in Spring to deal with requests and add some logic to them.
  • Services. Our service layer. Instead of using our service methods implemented in previous posts, we are going to hardcode some car objects for ease and so that the configuration files were smaller. Our service car is going to response a fixed car list.

Folder src/main/resources

Here, we can find our configuration files.

  • Locale. Our application will use JSP pages in our web browser language. It will need some files named with this message*.properties pattern. In these files we have to write our application literals in the language indicated by the * symbol. I mean, we could have a message-en.properties where there will be a property called title with the value, i.e., ‘Our application title’. Once our application is running it will use these properties to
  • Spring. In this folder we have to include our applicationContext.xml file. This file will load our application context when the application was running.
  • view_es.properties. This file isn’t going to be used yet. We are going to use it later to redirect request in our application.

Folder src/main/test

There is only one test class created. I have used Selenium framework to add some acceptance test. This test will open our web browser and running a sequence of actions (fill an input text, click a button, redirecting from one page to another, …). The next post I wrote will be related to the Selenium framework.

Folder src/main/webapp/WEB-INF

Here we have some folders and configuration files:

  • JSP folder. Here we are going to save our JSP pages. For the time being we are going to write our view layer as simple as we can. Later we could use some other framework such as ZKoss or any of JSF implementation.
  • Spring folder. Inside this folder there is a car-service.xml file. In this file we need to create a carService bean that we will use later when the application was running.
  • car-servlet.xml.This file will include in our DispatcherServlet context several beans. We include our car-service.xml so that we can use our CarService within our application.
    We need to add the annotation-config in our configuration file and we could use @Autowired annotation later in our java classes.

    <context:annotation-config />
    

    The next bean will map requests from car.html to our CarController. For other requests we are going to use a ControllerClassNameHandlerMapping.

    		<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
    			<property name="caseSensitive" value="true" />
    		</bean>
    

    As we have previously seen our views have to be resolved in a middle step between the controller and the view generation. We are going to use an InternalResourceViewResolver for that. This servlet will look up for jsp pages in the /WEB-INF/jsp context.

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

    In the following section we declare our interceptors. We create a TimeResponseInterceptor that is going to add a date value to our request. We need to include our interceptor in the configuration file using the BeanNameUrlHandlerMapping for that matter.

    	<bean id="timeResponseInterceptor" class="com.hopcroft.interceptor.TimeResponseInterceptor"></bean>
    	<bean
    		class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
    		<property name="interceptors">
    			<list>
    				<ref bean="timeResponseInterceptor"></ref>
    			</list>
    		</property>
    	</bean>
    

    This bean will resolve exceptions. If a CarException is thrown the carsNotAvailable will be rendered. If a java.lang.Exception is thrown the error.jsp will be shown. We can access to the exception value within this page using expression language ${exception}.

    	<bean	class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    		<property name="exceptionMappings">
    			<props>
    				<prop key="com.hopcroft.exception.CarException">carsNotAvailable</prop>
    				<prop key="java.lang.Exception">error</prop>
    			</props>
    		</property>
    	</bean>
    

    Finally we have to add a bean called carFromController which deal with the inclusion of new cars through a specified form. Instead of inyecting the carService with the @Autowired annotation we will pass as a reference. The view for our form will be mapped to a carForm page. When we had submitted sucessfully our form we have been redirected to a carInsertSucess page.

    	<bean id="carFormController" class="com.hopcroft.controller.CarFormController">
    		<property name="carService" ref="carService"></property>
    		<property name="formView" value="carForm"></property>
    		<property name="successView" value="carInsertSuccess"></property>
    	</bean>
    
  • web.xml. This is our application deployment file. There is some configuration we need to add to this file:
    • We are going to load our Spring context now.
      	<context-param>
      		<param-name>contextConfigLocation</param-name>
      		<param-value>classpath*:spring/applicationContext.xml</param-value>
      	</context-param>
      	<listener>
      		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      	</listener>
      
    • We need to annotate our DispatcherServlet and map our requests to a specified url pattern.
      	<servlet>
      		<servlet-name>car</servlet-name>
      		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      		<load-on-startup>1</load-on-startup>
      	</servlet>
      
      	<servlet-mapping>
      		<servlet-name>car</servlet-name>
      		<url-pattern>*.html</url-pattern>
      	</servlet-mapping>
      
      

Running our project

We have included the Maven Jetty plugin to test our JEE application, this way we don’t need a web container in our laptop. We have to execute the following Maven goals within our console:

mvn clean install -DskipTests
mvn jetty:run

Now we need to make a request to the two main pages in our application.

    • http://localhost:9080/spring-mvc/car.html The Dispatcher will forward the initial request to our CarController. The CarController code is pretty straightforward.
      public class CarController implements Controller {
      	@Autowired
      	private CarService carService;
      
      	public ModelAndView handleRequest(HttpServletRequest arg0,
      			HttpServletResponse arg1) throws Exception {
      		return new ModelAndView("car", "cars",  carService.getCars());
      	}
      

      Almost the whole application logic is within the car service class. It would better to deal with the application logic in our CarController.

      
      public class CarServiceImpl implements CarService {
      	public CarServiceImpl() {
      	}
      
      	public List<Car> getCars() throws CarException {
      		List<Car> cars = initCars();
      		if ((Calendar.getInstance().getTimeInMillis() % 2) == 0) {
      			return cars;
      		} else if ((Calendar.getInstance().getTimeInMillis() % 2) == 0) {
      			throw new CarException(1L, "Car service ", new Date());
      		} else
      			throw new RuntimeException();
      	}
      
      	// TODO: llamar al DAO de car.
      	private List<Car> initCars() {
      		List<Car> carList = new ArrayList<Car>();
      		Car car = new Car();
      		car.setBrand("Ferrari");
      		car.setName("F40");
      		car.setPrice(1000000L);
      
      		Car car2 = new Car();
      		car2.setBrand("Porsche");
      		car2.setName("Carrera");
      		car2.setPrice(200000L);
      
      		Car car3 = new Car();
      		car3.setBrand("Opel");
      		car3.setName("Astra");
      		car3.setPrice(18000L);
      
      		carList.add(car);
      		carList.add(car2);
      		carList.add(car3);
      
      		return carList;
      	}
      

      CarController will ask to a car list to our car service. Depending on the date when our CarController is accesed, it will returned:

        • A car list from the service car.

      carList

        • A CarException. As we previously seen these kind of exceptions will have their own JSP page so called carsNotAvailable where the request will be rendered

      carService

        • A generic java.lang.Exception linked to our standard error page

    • http://localhost:9080/spring-mvc/carForm.html. We have a pre-generated form with Spring MVC. The most interesting thing is that we can link a domain object to our form, so that Spring MVC will generate a html field linked to an attribute of one of our domain objects, Car in our case.
      public class CarFormController extends SimpleFormController {
      
      	public CarFormController() {
      		setCommandClass(Car.class);
      		setCommandName("carInsert");
      	}
      

CarForm MVC

CarFormResponse MVC

That’s all, I wish you found helpful this post to start with Spring MVC.

Greetings !!!

 
3 comentarios

Publicado por en 17 septiembre, 2011 en JEE, Spring MVC

 

Etiquetas: , , , ,

3 Respuestas a “Spring MVC basic example with Maven

  1. Flo Millora

    9 octubre, 2011 at 8:19 pm

    Hello Webmaster, I noticed that https://hop2croft.wordpress.com/2011/09/17/spring-mvc-basic-example-with-maven/ is ranking pretty low for some keywords, this may be due to the new Google Panda update, or it could be due to a variety of other factors. I’m sure you already know about On-page SEO, where Google cares highly about proper formatting of various H1/H2/H3 tags, having your main keyword appear in the beginning of your post and having your post end with the keyword, along with having keyword related alt tags and very relevant LSI. However, you do not seem to have the proper Keywords or relevant Keywords in your posts and in the website. Right now you need a tool or plugin that will allow you to check on Keyword insights, search trends and check for backlink analysis and to find out your Keyword competition. To find a Keyword Plugin that combines both Keyword Research and has the ability as a Rank Checker is what WordPress Seo Keyword, please check out our 5 minute video.

     

Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

 
Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 69 seguidores

%d personas les gusta esto: