May 21, 2009

Spring MVC - Example

« Create a simple RESTful Webservice with Jersey and Spring | Main | Spring Localization Example »

What is Spring MVC?
Spring MVC is a clearcut solution of the model view controller pattern. Apart from them the Spring MVC framework has a lot of additional useful functions. For example the validation of formulars.

In this article the basic Spring MVC principles will be described on the basis of the following example.
Steps are a login formular, validation of the username/password entries and a result page.

1. web.xml configuration:

First you have to add the ContextLoaderListener at web.xml file:

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

After that additional application contexts should be added:

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:web-ctx.xml</param-value>
</context-param>

Then you add the DispatcherServlet and the servlet mapping. That's the base Spring MVC servlet:

<servlet>
  <servlet-name>web</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>web</servlet-name>
  <url-pattern>/*.html</url-pattern>
</servlet-mapping>

2. Web Application Context:

The prefix of the application context is the servlet name of the dispatcher servlet definition at the web.xml file. That's why the file name is web-servlet.xml.

<!-- Data Validation -->
<bean id="loginFormValidator" class="org.developers.blog.examples.spring.mvc.LoginFormValidator"/>

<!-- Page Controller -->
<bean id="loginFormController" class="org.developers.blog.examples.spring.mvc.LoginFormController">
  <property name="validator" ref="loginFormValidator"/>
  <property name="formView" value="LoginForm.jsp"/>
  <!-- jump page, defined at urlMapping bean -->
  <property name="successView" value="ResultPage.html"/>
  <!-- alias name for command data object for accessing at the jsp page -->
  <property name="commandName" value="loginData"/>
  <!-- accessing data object -->
  <property name="commandClass" value="org.developers.blog.examples.spring.mvc.LoginFormData"/>
</bean>

<!-- controller of the result page -->
<bean id="resultPageController" class="org.developers.blog.examples.spring.mvc.ResultPageController">
</bean>

<!-- Mapping request URL to controller bean -->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="urlMap">
    <map>
      <entry key="Login.html"><ref bean="loginFormController"/></entry>
      <entry key="ResultPage.html"><ref bean="resultPageController"/></entry>
    </map>
   </property>
</bean>

<!-- view resolver -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
  <property name="prefix" value="/jsp/"/>
  <property name="suffix"><value></value></property>
</bean>

3. Beans, Controller und Validator

3.1 LoginFormData

public class LoginFormData {
    private String username;
    public void setUsername(String username) {
        this.username = username;
    }
    public String getUsername() {
        return this.username;
    }

    private String password;
    public void setPassword(String password) {
        this.password = password;
    }
    public String getPassword() {
        return this.password;
    }
}

3.2 FormController

public class LoginFormController extends SimpleFormController {

    @Override
    public ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception {
        LoginFormData formData = (LoginFormData)command;
        request.getSession().setAttribute("FORM_DATA", formData);
        ModelAndView modelAndView = new ModelAndView(new RedirectView(getSuccessView()));
        return modelAndView;
    }
    
}

3.3 ResultPageController

public class ResultPageController extends AbstractController {

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        return new ModelAndView("ResultPage.jsp");
    }

}

3.4 LoginFormValidator

public class LoginFormValidator implements Validator {

   public void validate(Object obj, Errors errors) {
      LoginFormData loginData = (LoginFormData)obj;

      if (loginData.getUsername() == null || loginData.getUsername().length() == 0) {
        errors.rejectValue("username", "error.empty.field", "empty username");
      } else if (!loginData.getUsername().equals("admin")) {
        errors.rejectValue("username", "unknown.user", "unknown user");
      }

      if (loginData.getPassword() == null || loginData.getPassword().length() == 0) {
        errors.rejectValue("password", "error.empty.field", "empty password");
      } else if (!loginData.getPassword().equals("password")) {
        errors.rejectValue("password", "wrong.password", "wrong password");
      }

   }

    public boolean supports(Class clazz) {
        return clazz.equals(LoginFormData.class);
    }
}

4. Definition of JSP pages - The View Components

4.1 LoginForm.jsp

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

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

<html>
    <body>
        <form:form commandName="loginData" method="POST">
            Username:<form:input path="username"/><form:errors path="username"/><br/>
            Password:<form:input path="password"/><form:errors path="password"/><br/>
            <input type="submit" value="login"/>
        </form:form>
    </body>
</html>

4.2 ResultPage.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<html>
    <body>
        <h1>Successful Login!</h1>
    </body>
</html>

The full Spring MVC example as maven project can be downloaded here. You can start the project with the maven jetty plugin. The command is "mvn clean install jetty:run".

Regards
Rafael Sobek

Technorati Tags:

Posted by rafael.sobek at 7:24 PM in Spring

 

[Trackback URL for this entry]

Comment: Mediocre-Ninja.blogSpot.com at Do, 18 Jun 2:57 AM

Thank you for sharing, but I didn't manage to run your provided project. The steps seem OK, but Jetty response was:

HTTP ERROR 404

Problem accessing /index.html. Reason:

NOT_FOUND


Am I missing some thing?

Comment: Rafael at Do, 18 Jun 7:42 AM

You have to run the following url: http://localhost:8080/Login.html.
Have a look at the "urlMapping" bean.

Comment: Mediocre-Ninja.blogSpot.com at Fr, 19 Jun 4:37 AM

After downloading your project and running maven command like above, the Jetty response was:

HTTP ERROR 404
Problem accessing /index.html. Reason:
NOT_FOUND


Am I missing something ?

Comment: Mediocre-Ninja.blogSpot.com at Fr, 19 Jun 4:40 AM

Thank you!
It works like a charm now !

Comment: hemant chouhan at Sa, 13 Feb 9:57 AM

when i run this above given app on netbeans5.0 the it show the error C:\Documents and Settings\hemant\Spring-Mvc1\nbproject\build-impl.xml:479: Deployment error:
and one more in the LoginForm.jsp like absolute uri uri="http://java.sun.com/jsp/jstl/core" cannt resolve in web.xml or jar files

Comment: Amit Patel at Do, 18 Mrz 10:52 AM

Thanks for sharing

Short and Sweet. keep sharing

Comment: LSRN at Di, 8 Jun 10:28 AM

Thanks. It is simple and yet self explanatory.

Comment: Harsh Vardhan at Do, 24 Jun 7:37 AM

It runs well in Net Beans. Thanks. A very good example for the beginners

Comment: cherry at So, 27 Jun 9:50 AM

Thanq mate..its short and simple...

Comment: muk at Do, 29 Jul 5:31 AM

This code really works very well.. thanks a lot..
One thing i wud like to know is this..
This code creates 1 form in the login.html

how do i create 2 forms in the same html page??

Comment: srinivasasuduram at Sa, 11 Dez 9:39 AM

it is very clear to understand all the things

Comment: shreya at Fr, 21 Jan 9:15 AM

isnt the html page given here?can someone tell me the step wise method to run this whole application

Comment: vijay at Di, 8 Feb 6:28 AM

good one to get first fill . do you have any more sample examples?

Comment: escapee at Mo, 7 Mrz 12:23 AM

Worked fine with eclipse and google app engine! :) perfect!

Comment: manoj at Mo, 2 Mai 7:26 AM

Good one for beginners

Comment: reddy at Di, 3 Mai 9:01 PM

hi,
i am a java developer and a newbie to spring mvc.Your article was very helpful in understanding the flow.I liked it specially because once some one understands the spring mvc architecture your sample is the best hands on to get a complete understanding of the mvc components.

Thanks

Comment: Faraz Md at Mo, 16 Mai 6:26 AM

Very good example...Just wanted to ask..Do we need to have "formView" & "SuccessView" as property for controlller configuration in dispatcher-servlet.xml ? (while doing form validation)

Comment: manish at Di, 6 Sep 5:59 AM

it's run on first time..
very nice and simple..
easy to understanding..

Comment: Samira DAHMANI at Mo, 26 Sep 3:50 PM

thanks for the sample, but you didn't mention where should web-ctx.xml be created and it's content ?

Comment: surendra at Mi, 28 Sep 6:04 AM

Thanks and Good one

Comment: Dharmendra at Fr, 11 Nov 11:59 AM

No mapping found for HTTP request with URI [/SpringTest/jsp/LoginForm.jsp] in DispatcherServlet with name 'dispatcher'

Comment: prasanna lakshmi at Mo, 5 Dez 10:27 AM

Hi all..
i am gettting Http 404 error while run the tomcat server 7.0 for simple basic login page using spring..pls give the solution for this problem

Comment: geofrey at Di, 17 Jan 10:34 AM

Hi,

How does one include the formview in another jsp to say display a bunch of data prior to the form, for example, youtube comments followed by the comments post form?

Your comment:

(not displayed)
 
 
 

Live Comment Preview: