Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Stereotype Annotations Cut Down XML Configuration in Spring : Page 3

Spring stereotype annotations can greatly reduce the amount of XML configuration required to build and maintain a Spring application.


advertisement

Stereotype Controllers

Like other stereotype components, the @Controller annotation lets you designate any Spring MVC controller as such without XML configuration. For example, the following is a simple Spring MVC controller (extending AbstractController) annotated with the @Controller stereotype annotation:

@Controller public class HelloWorldController extends AbstractController { protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { String name = request.getParameter("name"); return new ModelAndView("greet", "name", name); } }

Figure 2. Three MVC Components That Must Be Configured: The three major components that must be constructed and configured (usually via XML) to make a Spring MVC application work include the handler mapping, controller, and view resolver.



Controllers are one of three MVC components that usually have to be configured in XML in order to handle any web request. The other two are handler mappings and view resolvers (see Figure 2).

By itself, the @Controller annotation removes one of the three big MVC components from the Spring XML configuration (as shown by the following sample configuration). However, as you will see, additional Spring 2.5 controller annotations can remove the need to configure one of the other MVC components as well.

<bean class= "org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <value> /greeting.request=greetingController </value> </property> </bean> <!-- <bean id="greetingController" class="com.intertech.mvc.HelloWorldController" /> --> <bean class= "org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="" /> <property name="suffix" value=".jsp" /> </bean>

To help explain the important annotations associated with the controller component, the code download for this article contains two small Java Eclipse projects:

  • HelloWorldOriginal.zip is a Spring MVC Hello World application pre-annotations.
  • HelloWorldAnnotated.zip is a Spring MVC application with the new stereotype annotations.

The sample configuration above shows the simple HelloWorldController annotated with the new @Controller stereotype annotation. By the way, as with any other stereotype component, you can explicitly name and scope the controller by annotation as shown here:

@Controller("greetingController") @Scope("prototype") public class HelloWorldController extends AbstractController { ... }

As mentioned previously, many additional annotations are provided in the Spring MVC library to work with the @Controller annotation. Also note that the MVC annotations are available for either the web (a.k.a. Servlet) or Portlet MVC environments.

RequestMapping by Annotation

When building Spring beans or components, those beans should not have to extend any Spring class or implement a Spring interface. In rare cases when Spring provides an interface or class that your bean implements or extends, the documentation is less than coy in its warnings. Take, for example, the documentation for the InitializingBean interface, which allows initialization work to occur after all properties on a bean have been set:
Generally, the use of the InitializingBean interface can be avoided and is actually discouraged since it unnecessarily couples the code to Spring.

Wait a minute! Have you examined your Spring MVC components lately? Almost all of the Spring MVC components, from handler mappings to views, require the extension or implementation of a Spring MVC class or interface! @Controller alone doesn't fix this (check out HelloWorldController again). Some, including members of the Spring development team, have recognized this as intrusive. The @RequestMapping annotation helps remove this coupling, at least as far as controllers are concerned.

The @RequestMapping annotation, working with the @Controller annotation, maps request URLs to a controller. You can use this annotation on the controller type itself or on the controller methods. When the @RequestMapping annotation is used on the controller class (type-level annotation), it directs specific requests to the controller. For example, the @RequestMapping annotation here directs all requests for http://.../greeting.request to the HelloWorldController.

@Controller @RequestMapping("/greeting.request") public class HelloWorldController extends AbstractController { protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception { String name = request.getParameter("name"); return new ModelAndView("greet", "name", name); } }

The @RequestMapping annotation, along with the @Controller stereotype annotation, simplifies MVC development in a couple of ways:

  1. The @RequestMapping does the job of the Spring MVC handler mapping! Therefore, the handler mapping configuration is not required. The XML configuration just got smaller again.
  2. The @RequestMapping also took away the need to name the controller, which is usually used by handler mappings. Note the @Controller annotation is without a name parameter.

So now, because of the @Controller and @RequestMapping annotations, two of the three major Spring MVC components (the handler mapping and controller) do not need to be configured in XML. You need only the view resolver to configure an MVC set of components to handle a request:

<context:component-scan base-package="com.intertech"/> <!-- <bean class= "org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <value> /greeting.request=greetingController </value> </property> </bean> <bean id="greetingController" class="com.intertech.mvc.HelloWorldController" /> --> <bean class= "org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="" /> <property name="suffix" value=".jsp" /> </bean>

When you use @RequestMapping on methods of the controller (called method-level annotation), it eliminates the need to couple the controller to any type. Any class can serve in the role of controller, and the @RequestMapping on the method guides request traffic to the specific methods defined in the class. No longer do controllers have to extend or implement a Spring MVC controller class or interface! In fact, the controller classes don't even have to have an attachment to the Servlet API:

@Controller public class HelloWorldController { @RequestMapping("/greeting.request") protected String sayHello (){ return "greet"; } }

Note that the request-mapping annotation can use a '*' so that the multiple-request URLs are mapped to a single controller or controller method (see below).

@RequestMapping(value="/*.request",method=RequestMethod.POST) protected String sayHello (){ return "greet"; }

Given the method-level @RequestMapping annotations, multi-action controllers are a breeze to develop. In fact, multi-action controllers get implemented no differently than other controllers. A multi-action controller using controller annotations might look like this:

@Controller public class CustomerController { @RequestMapping("/addCustomer.request") public String addCustomer() { //do the work to add a customer } @RequestMapping("/deleteCustomer.request") public void deleteCustomer() { //do the work to delete a customer } @RequestMapping("/displayCustomer.request") public String displayCustomer() { //do the work to retrieve a customer } }

You can use the @RequestMapping to further specify which method to call for a request. That is, @RequestMapping focuses specific HTTP method (GET, POST, etc.) requests to specific handler methods within the controller. For example, the type-level annotation here routs the request URLs to the controller.

@Controller @RequestMapping("/greeting.request") public class HelloWorldController { @RequestMapping(method=RequestMethod.POST) protected String sayHello (){ return "greet"; } @RequestMapping(method=RequestMethod.GET) protected String showForm (){ return "getname"; } }

You can accomplish the type-level and method-level annotations above entirely at the method-level as shown here:

@Controller public class HelloWorldController { @RequestMapping(value="/greeting.request",method=RequestMethod.POST) protected String sayHello (){ return "greet"; } @RequestMapping(value="/greeting.request",method=RequestMethod.GET) protected String showForm (){ return "getname"; } }

The ability to use @RequestMapping to route requests based on URLs as well as HTTP methods allows any class to serve in a behavior similar to that of form controllers.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap