2011-01-07 9 views

Odpowiedz

61

A @Controller to bardziej elastyczny sposób definiowania formularza/kreatora. Powinieneś mapować metody na zapytania w oparciu o żądaną ścieżkę/parametry żądania/metodę żądania. Zamiast więc definiować listę widoków i przetwarzać żądanie na podstawie wymaganego parametru "krok", możesz zdefiniować kroki kreatora, jak chcesz (również obiekt polecenia będzie obsługiwany w bardziej przejrzysty sposób). Oto, jak można emulować klasyczną funkcjonalność AWFC (ma to być tylko przykład, można zrobić o wiele więcej).

@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"; 
    } 

} 

Próbowałem zmieniać sygnatur metod, dzięki czemu można uzyskać wyobrażenie o elastyczności wspominałem. Oczywiście, nie ma dużo więcej do niej: można skorzystać z metody żądania (GET lub POST) w @RequestMapping można zdefiniować metodę uwagami z @InitBinder itd

EDIT: miałem metodę niemapowany które naprawiłem (przy okazji, musisz się upewnić, że nie masz dwuznacznych mapowań - żądań, które można zmapować na więcej niż jedną metodę - lub nieodwzorowane żądania - żądania, które nie mogą być odwzorowane na żadną metodę). Zobacz także @SessionAttributes, @SessionStatus i @ModelAttribute, które są również potrzebne do pełnej symulacji zachowania klasycznego AWFC (redagowałem już kod, aby było jasne).

+5

+1 Jest to z pewnością lepsze wyjaśnienie niż to, co zapewnia aplikacja Spring documentation/example. Wiele osób może uznać to za pomocne. – prasopes

+0

Tak, bardzo, bardzo pomocny. – false9striker

+1

Jest to pomocne, ale nie ma wyjaśnienia metody 'pageViews'. – djangofan

Powiązane problemy