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).
+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
Tak, bardzo, bardzo pomocny. – false9striker
Jest to pomocne, ale nie ma wyjaśnienia metody 'pageViews'. – djangofan