Pages

Thursday, August 5, 2010

Spring - MultiActionController


Generally we have mapping in xml file for dispatcher servlet to decide which controller to use as per URL mapping but if we have to take decision on basis of request parameters then MultiActionController can be used.
Spring offers a multi-action controller with which multiple actions can be aggregated into one controller, grouping functionality together. The multi-action controller is capable of mapping requests to method names and then invoking the right method name. Using the multi-action controller is especially handy when you have a lot of common functionality in one controller, but want to have multiple entry points to the controller.
Using Spring MultiActionController class you can group related actions into a single controller class. The handler method for each action should be in the following form.


public (ModelAndView | Map | String | void) actionName(HttpServletRequest, HttpServletResponse [,HttpSession] [,CommandObject]);

Ex: public ModelAndView add(HttpServletRequest req,HttpServletResponse res)



May take a third parameter HttpSession in which an existing session will be required, or a third parameter of an arbitrary class that gets treated as command (i.e. an instance of the class gets created, and request parameters get bound to it)

These methods can throw any kind of exception, but should only let propagate those that they consider fatal, or which their class or superclass is prepared to catch by implementing an exception handler.

This model allows for rapid coding, but loses the advantage of compile-time checking. It is similar to a Struts 1.1 DispatchAction, but more sophisticated. Also supports delegation to another object.

An implementation of the MethodNameResolver interface defined in this package should return a method name for a given request, based on any aspect of the request, such as its URL or an "action" parameter. The actual strategy can be configured via the "methodNameResolver" bean property, for each MultiActionController.

The default MethodNameResolver is InternalPathMethodNameResolver; further included strategies are PropertiesMethodNameResolver and ParameterMethodNameResolver.

Subclasses can implement custom exception handler methods with names such as:

 ModelAndView anyMeaningfulName(HttpServletRequest request, HttpServletResponse response, ExceptionClass exception);

The third parameter can be any subclass or Exception or RuntimeException.
There can also be an optional lastModified method for handlers, of signature:

 long anyMeaningfulNameLastModified(HttpServletRequest request)

If such a method is present, it will be invoked. Default return from getLastModified is -1, meaning that the content must always be regenerated.
Note that method overloading isn't allowed.

Example
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
        <servlet-name>disp</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>disp</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>



index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
   </head>
    <body>
<a href="user/add.htm" >Add</a> <br>
<a href="user/remove.htm" >Remove</a>
  </body>
</html>

We have declared the welocme file as index.jsp in web.xml file so first request comes to index.jsp. if user clicks the add/remove, container receives the request and checks the extension of the request here it is *.htm and invokes the corresponding servlets(DispatcherServlet). In web.xml we have declared the servlet name as disp so DispatcherServlet checks the disp-servlet.xml file only. If it is not available then its throws an exception.
disp-servlet.xml
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/" p:suffix=".jsp" />
<bean name="/user/*.htm" class="com.UserController" />
</beans>
Here we use the BeanNameUrlHandlerMapping to map the request url. Our request contains add.htm so it invokes the matched bean in our case its UserController.
So to map multiple actions, we use the asterisk character. Anything that matches the asterisk character will be considered as the method name in the UserController class.
UserController.java
package com;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

public class UserController extends MultiActionController {
public ModelAndView add(HttpServletRequest request,
HttpServletResponse response) throws Exception {
System.out.println("Add method called");
return new ModelAndView("success", "message", "Add method called");
}
public ModelAndView remove(HttpServletRequest request,
HttpServletResponse response) throws Exception {
System.out.println("Remove method called");
return new ModelAndView("success", "message", "Remove method called");
}
}
To group multiple actions your controller class should extend MultiActionController class. Here the UserController class extends the MultiActionController class and contains the add() and the remove() method 
Each method return ModelAndView object which contains jsp name, message key and value.
container checks the name of the parameter in the ModelAndView object and invokes the corresponding jsp page in our case its success.jsp
Success.jsp



<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Success Page</title>
</head>
<body>
${message}
</body>
</html>
using EL functions, we will get the value by passing the Key. ${message}

Output

if user clicks on Add

No comments:

Post a Comment