You are on page 1of 10

MultiActionController with Validation

Description: Spring supports a multiaction controller where the


multiple actions on a form can be grouped to a single controller. The
multiaction controller supports the mapping of requests to method
names which are similar to what Dispatch Action of struts do and it
does a bit more than that in terms of delegation of the requests.

Problem Description: A Simple Login page with two buttons, which take
user name and password as the inputs. The page has two buttons,
authenticate and login as shown below and performs validation on
click of the buttons.

Implementation:

Step 1: Configuring the spring main servlet (DispatcherServlet) in


web.xml

In the web.xml we have named the servlet as spring; hence the spring
context file is required to be named as spring-servlet.xml
Step 2: Configuring the LoginController(MultiActionController) and
the LoginValidator in spring-servlet.xml

The LoginController has the two setter methods


• setMethodNameResolver – this identifies the method that is
mapped to a particular request, the MethodNameResolver takes
two values
o paramName – The hidden variable that we declare in the
login.jsp page, whose value needs to be set as the name
of the method name in the controller.
o defaultMethodName – The method name of the controller
that is executed when the page is loaded.

• setValidators – this identifies the set of vallidators that the


controller can execute in our example LoginValidator

Step3 : Creating the login page login.jsp

We have two buttons Authenticate and Register, which when clicked


invoke the javascript method setAction() which will set the value of
the hidden variable by name methodToCall which is configured in the
spring-servlet.xml as the paramName which identifies the name of the
method of the controller class to be invoked.

<%@ taglib prefix="form"


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

<script type="text/javascript">
function setAction(action1){
document.forms[0].methodToCall.value = action1;
document.forms[0].submit();
}
</script>
<style>
.error { color: red; }
</style>

<c:if test="${not empty errors}">


<div class="error">
<c:forEach var="error" items="${errors}">
<c:out value="${error}" escapeXml="false"/><br />
</c:forEach>
</div>
</c:if>
<form:form method="post" commandName="command" >
<table width="95%" bgcolor="f8f8ff" border="0" cellspacing="0"
cellpadding="5">
<tr>
<td align="right" width="20%">UserId</td>
<td width="20%">
<spring:bind path="command.userid">
<form:input path="userid"/>
</spring:bind>
</td>
<td width="60%">
<form:errors path="userid" cssClass="error"/>
</td>
</tr>
<tr>
<td align="right" width="20%">Password</td>
<td width="20%">
<spring:bind path="command.password" >
<form:input path="password"/>
</spring:bind>
</td>
<td width="60%">
<form:errors path="password" cssClass="error"/>
</td>
</tr>
<tr>
<td align="right" width="20%" >
<input type="button" align="middle" value="Authenticate"
onclick="javascript:setAction('authenticateUser');" >
</td><td width="20%" >
<input type="button" align="middle" value="Register"
onclick="javascript:setAction('registerUser');">

</td>

</tr>

</table>
<br>
<input type="hidden" name="methodToCall" value="" />
</form:form>
</body>
</html>
Step 4: Creating the controller Login Controller:

package com.spring.controller;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import
org.springframework.web.servlet.mvc.multiaction.MultiActionController
;

public class LoginController extends MultiActionController {

BindingResult errors;

public BindingResult getErrors() {


return errors;
}

public void setErrors(BindingResult errors) {


this.errors = errors;
}

@Override
protected void bind(HttpServletRequest request, Object command)
throws Exception {
// TODO Auto-generated method stub
ServletRequestDataBinder binder = createBinder(request,
command);
binder.bind(request);
errors = binder.getBindingResult();
}

public ModelAndView login(HttpServletRequest request,


HttpServletResponse response , Object command){

PropertyConfigurator.configure("C:\\log4j.properties");
Logger logger = Logger.getLogger(BasicController.class);

logger.debug("Opening Login page: ");


logger.warn("Opening Login page: ");
ModelAndView model = new ModelAndView("login");
model.addObject("command", new Login());
return model;
}
public ModelAndView authenticateUser(HttpServletRequest request,
HttpServletResponse response , Login command){

System.out.println("Authenticating user : ");


validate(command);
Login login = (Login)command;
if (errors.hasErrors()) {
System.out.println("Error Handling : ");
saveError(request,
errors.getFieldError().getCode());
return new ModelAndView("login","command",login);
}

System.out.println("Login Successfull : ");

return new ModelAndView("loginsuccess","command",login);


}

public ModelAndView registerUser(HttpServletRequest request,


HttpServletResponse response , Login command){

System.out.println("registerUser user : ");


Login login = (Login)command;

return new
ModelAndView("registrationsuccess","command",login);

public void validate(Object command) {


Validator[] validators = getValidators();
if (validators != null) {
for (int index = 0; index < validators.length;
index++) {
Validator validator = validators[index];
if (validator instanceof LoginValidator) {
if (((LoginValidator)
validator).supports(command
.getClass())) {

ValidationUtils.invokeValidator(validators[index],
command, errors);
}
} else if
(validator.supports(command.getClass())) {

ValidationUtils.invokeValidator(validators[index], command,
errors);
}
}
}
}

public void saveError(HttpServletRequest request, String msg) {


List errors = (List) request.getAttribute("errors");
if (errors == null) {
errors = new ArrayList();
}
errors.add(msg);
request.setAttribute("errors", errors);
}

Explaination:

1. The default method name that we have defined in the spring-


servlet.xml is login, so the controller will define a method by name
login as below

This method will just route the request to the view to the login.jsp
when we access the url
http://localhost::8080/<ContextName>/login.htm (login.htm is
resolved as login.jsp by the resolver)

The methods authenticateUser and registerUser methods are invoked


when the user clicks the buttons.The code snippet for the same is as
below
Step 5: Validation

For the validation in MultiActionController unlike SimpleFormController we need to override the bind
and the validate methods in the controller
For the errors to appear on the login page back we need to set the errors to the request object as shown
below
Running the complete example

Press on Authenticate as the user id is different from 12345 which is given in the Validator, error would
be thrown
Step6: Success Page

If the input is given as 12345 it would be successfully redirected to the next page

Press on authenticate which would take the user to success page

Thank You,
Santosh Kothapalli SCWCD

You might also like