Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AbstractWizardFormController using Annotated @Controllers

In Spring Framework , AbstractWizardFormController seems deprecated. How to implement multiple pages form in the Spring MVC Framework. (I am not using webflow)

any example or pointer would help considering my limited knowledge in Spring.

like image 289
Sourabh Avatar asked Jan 07 '11 08:01

Sourabh


People also ask

What is the preferred way to designate a class is a controller?

The @Controller annotation indicates that a particular class serves the role of a controller. Spring Controller annotation is typically used in combination with annotated handler methods based on the @RequestMapping annotation. It can be applied to classes only. It's used to mark a class as a web request handler.

Which controller is intended to use with multipage webforms?

Multipage / Wizard Form Validation In SimpleFormController , you create a validator class, put all the validation logic inside the validate() method, and register the validator to the simple form controller decoratively.

Which design pattern is implemented by dispatcher?

Design pattern implemented by Dispatcher Servlet. Explanation: A Spring MVC controller—often referred to as a Dispatcher Servlet—implements one of Sun's core Java EE design patterns called front controller.

Which of the following controller combines multiple request handling methods into one controller?

Multi-Action Controller: According to the Spring official documentation, MultiActionController is a Controller implementation that allows multiple request types to be handled by the same class. Subclasses of this class can handle several different types of requests with methods of the form.


1 Answers

A @Controller is a more flexible way to define a form / wizard. You are supposed to map methods to requests based on requested path / request parameters / request method. So instead of defining a list of views and processing the request based on some required "step" parameter, you can define the steps of your wizard as you wish (also the command object will be handled more transparently). Here's how you can get to emulate a classic AWFC functionality (this is only meant to be an example, there's a lot more you can do).

@Controller @RequestMapping("/wizard.form") @SessionAttributes("command") public class WizardController {      /**      * The default handler (page=0)      */     @RequestMapping     public String getInitialPage(final ModelMap modelMap) {         // put your initial command         modelMap.addAttribute("command", new YourCommandClass());         // populate the model Map as needed         return "initialView";     }      /**      * First step handler (if you want to map each step individually to a method). You should probably either use this      * approach or the one below (mapping all pages to the same method and getting the page number as parameter).      */     @RequestMapping(params = "_step=1")     public String processFirstStep(final @ModelAttribute("command") YourCommandClass command,                                    final Errors errors) {         // do something with command, errors, request, response,         // model map or whatever you include among the method         // parameters. See the documentation for @RequestMapping         // to get the full picture.         return "firstStepView";     }      /**      * Maybe you want to be provided with the _page parameter (in order to map the same method for all), as you have in      * AbstractWizardFormController.      */     @RequestMapping(method = RequestMethod.POST)     public String processPage(@RequestParam("_page") final int currentPage,                               final @ModelAttribute("command") YourCommandClass command,                               final HttpServletResponse response) {         // do something based on page number         return pageViews[currentPage];     }      /**      * The successful finish step ('_finish' request param must be present)      */     @RequestMapping(params = "_finish")     public String processFinish(final @ModelAttribute("command") YourCommandClass command,                                 final Errors errors,                                 final ModelMap modelMap,                                 final SessionStatus status) {         // some stuff         status.setComplete();         return "successView";     }      @RequestMapping(params = "_cancel")     public String processCancel(final HttpServletRequest request,                                 final HttpServletResponse response,                                 final SessionStatus status) {         status.setComplete();         return "canceledView";     }  } 

I tried to vary the method signatures so that you can get an idea about the flexibility I mentioned. Of course, there's a lot more to it: you can make use of request method (GET or POST) in the @RequestMapping, you can define a method annotated with @InitBinder, etc.

EDIT: I had an unmapped method which I fixed (by the way, you need to make sure you don't have ambiguous mappings -- requests that could be mapped to more than one method -- or unmapped requests -- requests that cannot be mapped to any method). Also have a look at @SessionAttributes, @SessionStatus and @ModelAttribute, which are also needed for fully simulating the behaviour of the classic AWFC (I edited the code already to make this clear).

like image 192
Costi Ciudatu Avatar answered Oct 03 '22 19:10

Costi Ciudatu