Sei sulla pagina 1di 7

blog.m1key.

me: Wizard form with Spring MVC

http://blog.m1key.me/2011/10/wizard-form-with-spring-mvc.html

More

Next Blog

Create Blog

Sign In

BLOG.M1KEY.ME
JAVA, JEE, SPRIN G, PHOTO GRAPHY BL OG.

2011-10-30

ABOUT ME M ICHA HU N IE WI CZ

Wizard form with Spring MVC

Micha Huniewicz is a software engineer, currently living in England.


V IE W M Y C O M PL E T E PR O F I L E

FOLLOWERS

with Google Friend Connect

Members (80) More

Already a member? Sign in

A FEW LINKS...

My GitHub My Homepage My photos Tamara BeJot [PL]

L ABEL S

Programming

Java

Photography Maven JBoss Scala JPA Spring Hibernate CDI


HSQLDB JSF REST Gradle Guice

1 of 7

6/30/2013 1:57 PM

blog.m1key.me: Wizard form with Spring MVC

http://blog.m1key.me/2011/10/wizard-form-with-spring-mvc.html

Today I will show you how to create a wizard form with Spring MVC. A wizard form is a multi-step form that allows users to submit information gradually. With Spring MVC it's very easy to make such a form, as well as validate already submitted data on each step and on finish. Controller
BL OG ARCHIVE

This is the main thing. Let's take a detailed look. The controller is annotated with the @Controller annotation. @RequestMapping specifies its path. Also, we are storing user submitted data (an instance of my custom transfer object called PersonTo) in session with the @SessionAttributes annotation.
@Controller @RequestMapping("/personRegistration") @SessionAttributes("personTo") public class PersonRegistrationController {

2013 (11) 2012 (33) 2011 (27) December (3) November (1) October (3) Wizard form with Spring MVC JEE6: Integration testing with JBoss 7 jQuery UI Autocomplete + Spring MVC September (2) August (1) July (3) May (9)

Now, let's take a look at initialisation code. The controller expects an appropriate validator to be passed during construction time. The validator is, in our case, a Spring bean, so we can have it autowired. Then we initialise an init binder for the custom Gender enum. That allows incoming string parameters to be converted into enum instances.
@Autowired

public PersonRegistrationController(PersonRegistrationValidator valida super(); this.validator = validator; }

April (2)

March (3) 2010 (53)

@InitBinder public void initBinder(WebDataBinder binder) {

SEARCH THIS BL OG

binder.registerCustomEditor(Gender.class, new GenderEditor()); }

Loading...

Next, look at the method that handles GET requests. This method resets the potentially submitted data by creating a new PersonTo object and storing it in session. It requests the registration name form to be displayed. (The forms code will soon follow)
@RequestMapping(method = RequestMethod.GET) public String setupForm(Model model) { PersonTo personTo = new PersonTo(); model.addAttribute(PERSON_TO, personTo); return REGISTRATION_NAME_FORM;

2 of 7

6/30/2013 1:57 PM

blog.m1key.me: Wizard form with Spring MVC

http://blog.m1key.me/2011/10/wizard-form-with-spring-mvc.html

And now the big thing. The method that handles POST requests which are those where the user actually submitted data.
@RequestMapping(method = RequestMethod.POST) public String submitForm(HttpServletRequest request, HttpServletResponse response, @ModelAttribute(PERSON_TO) PersonTo personTo, BindingResult re SessionStatus status, @RequestParam("_page") int currentPage, Model model) {

Map<Integer, String> pageForms = new HashMap<Integer, String>(); pageForms.put(0, REGISTRATION_NAME_FORM); pageForms.put(1, REGISTRATION_GENDER_FORM);

if (userClickedCancel(request)) { status.setComplete(); return REDIRECT_TO_HOMEPAGE; } else if (userIsFinished(request)) { validator.validate(personTo, result); if (result.hasErrors()) { return pageForms.get(currentPage); } else { log.info("Registration finished for person [{}: {}].", personTo.getGender(), personTo.getName()); personTo.setRegistrationComplete(true); return REDIRECT_TO_SUCCESS_PAGE; } } else { int targetPage = WebUtils.getTargetPage(request, "_target", currentPage); if (userClickedPrevious(currentPage, targetPage)) { return pageForms.get(targetPage); } else { switch (currentPage) { case 0: validator.validateName(personTo, result); break; } case 1: validator.validateGender(personTo, result); break; }

if (result.hasErrors()) {

3 of 7

6/30/2013 1:57 PM

blog.m1key.me: Wizard form with Spring MVC

http://blog.m1key.me/2011/10/wizard-form-with-spring-mvc.html

return pageForms.get(currentPage); } else { return pageForms.get(targetPage); } } } }

1. If the user clicked cancel, cancel the whole thing by ending the session and redirect to the home page. 2. If the user is finished, validate the whole session stored transfer object. Redirect to success page or display errors. 3. Otherwise, this is another step in the wizard. In that case, establish which step it is and apply correct validation. If there are errors, show the current page where Spring will display error messages. If everything is OK, go to the next page. View I'm using Velocity. Here's the first form where the user types their name. Look at the Next and Cancel buttons (the names are important, _target1 and _cancel) and at the hidden input with page number (zero, since this is the first page in the wizard).
<form method="post" modelAttribute="personTo"> <table> <tr> <td>Your name:</td> <td>#springFormInput("personTo.name" "") </td> <td>#springShowErrors("" "") </td> </tr> <tr> <td colspan="3"> <input type="submit" value="Next" name="_target1"> <input type="submit" value="Cancel" name="_cancel" <input type="hidden" value="0" name="_page"> </td> </tr> </table> </form>

And the gender selection page. Note we are using a drop down list here.
<form method="post" modelAttribute="personTo"> <table>

4 of 7

6/30/2013 1:57 PM

blog.m1key.me: Wizard form with Spring MVC

http://blog.m1key.me/2011/10/wizard-form-with-spring-mvc.html

<tr> <td>Your gender:</td> <td>#springFormSingleSelect("personTo.gender" $genders </td> <td>#springShowErrors("" "") </td> </tr> <tr> <td colspan="3"> <input type="submit" value="Previous" name="_targe <input type="submit" value="Finish" name="_finish" <input type="submit" value="Cancel" name="_cancel" <input type="hidden" value="1" name="_page"> </td> </tr> </table> </form>

Property editor Here's the GenderEditor, if you're interested.


public class GenderEditor extends PropertyEditorSupport {

@Override public String getAsText() { if (getValue() == null) { return null; } else { Gender gender = (Gender) getValue(); return gender.toString(); } }

@Override public void setAsText(String text) throws IllegalArgumentException { if (StringUtils.isEmpty(text)) { setValue(""); } else if (text.equalsIgnoreCase("m")) { setValue(Gender.MALE); } else if (text.equalsIgnoreCase("f")) { setValue(Gender.FEMALE); } else if (text.equalsIgnoreCase("o")) { setValue(Gender.OTHER); } }

5 of 7

6/30/2013 1:57 PM

blog.m1key.me: Wizard form with Spring MVC

http://blog.m1key.me/2011/10/wizard-form-with-spring-mvc.html

We need the getAsText() method for validation purposes. That makes sure that if an unknown value is passed from the view, the resulting value is null (as opposed to the String "null"). Download the source code The source code for this is available on GitHub.
PO ST E D BY M I C H A H U N IE W IC Z A T 7 : 4 7 PM L A BE L S: J A V A , PR O GR A M M IN G, SPR I N G, V E L O C I T Y

2 COMMEN TS: Rossen Stoyanchev November 1, 2011 at 3:18 PM This is a good case for using Spring Web Flow. If your application has a few of these wizards. Reply

Micha Huniewicz

November 1, 2011 at 11:35 PM

Hi Rossen, thanks for your comment. I am going to look into Spring Web Flow in future. Reply Add comment

Comment as:

Newer Post

Home

Older Post

Subscribe to: Post Comments (Atom)

6 of 7

6/30/2013 1:57 PM

blog.m1key.me: Wizard form with Spring MVC

http://blog.m1key.me/2011/10/wizard-form-with-spring-mvc.html

7 of 7

6/30/2013 1:57 PM

Potrebbero piacerti anche