Spring MVC обрабатывает многостраничные формы с помощью AbstractWizardFormController

Spring MVC обрабатывает многостраничные формы с помощью AbstractWizardFormController

В последнемSpring MVC form handling example мы должны использоватьSimpleFormController для обработки отправки одностраничной формы, что довольно просто и легко.

Но, иногда, вам может понадобиться иметь дело с «wizard form», для которого нужно обрабатывать форму на несколько страниц и просить пользователя заполнять форму постранично. Основная проблема в этой ситуации в форме мастера - как сохранить данные модели (данные, заполненные пользователем) и перенести их на несколько страниц?

SAbstractWizardFormController

К счастью, Spring MVC поставляется с классомAbstractWizardFormController, чтобы легко обрабатывать эту форму мастера. В этом руководстве мы покажем вам, как использовать классAbstractWizardFormController для хранения и переноса данных формы на несколько страниц, применения проверки и отображения данных формы на последней странице.

1. Страницы форм мастера

5 страниц для этой демонстрации, работают в следующих последовательностях:

[User] --> WelcomePage --> Page1 --> Page2 --> Page3 --> ResultPage

СAbstractWizardFormController последовательность страниц определяется «именем» кнопки отправки:

  1. _finish: завершить форму мастера.

  2. _cancel: отменить форму мастера.

  3. _targetx: перейти на целевую страницу, где x - это нулевой индекс страницы. e.g _target0, _target1 and etc.

1. WelcomePage.jsp
Страница приветствия с гиперссылкой для запуска процесса формы мастера.



    

Handling multipage forms in Spring MVC

Click here to start playing - AbstractWizardFormController example

2. Page1Form.jsp
Страница 1, с текстовым полем «имя пользователя», отображает сообщение об ошибке, если таковое имеется, и содержит 2 кнопки отправки, где:

  1. _target1 - перейти на страницу 2.

  2. _cancel - отменить процесс формы мастера и переместить его на страницу отмены

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>






    

Page1Form.jsp

Username :

3. Page2Form.jsp
Страница 2, с полем «пароль», отображает сообщение об ошибке, если таковое имеется, и содержит 3 кнопки отправки, где:

  1. _target0 - перейти на страницу 1.

  2. _target2 - перейти на страницу 3.

  3. _cancel - отменить процесс формы мастера и переместить его на страницу отмены

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>






    

Page2Form.jsp

Password :

4. Page3Form.jsp
Страница 3, с текстовым полем «примечание», выводит сообщение об ошибке, если таковое имеется, и содержит 3 кнопки отправки, где:

  1. _target1 - перейти на страницу 2.

  2. _finish - завершить процесс формы мастера и переместить его на конечную страницу.

  3. _cancel - отменить процесс формы мастера и переместить его на страницу отмены.

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>






    

Page3Form.jsp

Remark :

5. ResultForm.jsp
Отображение всех данных формы, собранных с предыдущих 3 страниц.



    

ResultForm.jsp

UserName : ${user.userName}
Password : ${user.password}
Remark : ${user.remark}

2. модель

Создайте класс модели для хранения данных формы.

Файл: User.java

package com.example.common.model;

public class User{

    String userName;
    String password;
    String remark;

    //getter and setter methods
}

3. AbstractWizardFormController

РасширяетAbstractWizardFormController, просто переопределив следующие методы

  1. processFinish– срабатывает, когда пользователь нажимает кнопку отправки с именем «_finish».

  2. processCancel - срабатывает, когда пользователь нажимает кнопку отправки с именем «_cancel».

  3. formBackingObject - Используйте класс модели «Пользователь» для хранения всех данных формы на нескольких страницах.

Файл: UserController.java

package com.example.common.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractWizardFormController;
import com.example.common.model.User;
import com.example.common.validator.UserValidator;

public class UserController extends AbstractWizardFormController{

    public UserController(){
        setCommandName("userForm");
    }

    @Override
    protected Object formBackingObject(HttpServletRequest request)
        throws Exception {

        return new User();
    }
    @Override
    protected ModelAndView processFinish(HttpServletRequest request,
        HttpServletResponse response, Object command, BindException errors)
        throws Exception {

        //Get the data from command object
        User user = (User)command;
        System.out.println(user);

        //where is the finish page?
        return new ModelAndView("ResultForm", "user", user);
    }

    @Override
    protected ModelAndView processCancel(HttpServletRequest request,
        HttpServletResponse response, Object command, BindException errors)
        throws Exception {

        //where is the cancel page?
        return new ModelAndView("WelcomePage");
    }
}

Простой контроллер, возвращающий представление «WelcomePage».

Файл: WelcomeController.java

package com.example.common.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class WelcomeController extends AbstractController{

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
        HttpServletResponse response) throws Exception {

        return new ModelAndView("WelcomePage");
    }

}

4. Проверка многостраничной формы / формы мастера

ВSimpleFormController вы создаете класс валидатора, помещаете всю логику валидации в методvalidate() и декоративно регистрируете валидатор в контроллере простой формы.

Но вAbstractWizardFormController все немного по-другому. Сначала создайте класс валидатора, а также метод валидации для каждой страницы, как показано ниже:

Файл: UserValidator.java

package com.example.common.validator;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.example.common.model.User;

public class UserValidator implements Validator{

    @Override
    public boolean supports(Class clazz) {
        //just validate the User instances
        return User.class.isAssignableFrom(clazz);
    }

    //validate page 1, userName
    public void validatePage1Form(Object target, Errors errors) {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userName",
                "required.userName", "Field name is required.");
    }

    //validate page 2, password
    public void validatePage2Form(Object target, Errors errors) {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password",
            "required.password", "Field name is required.");
    }

    //validate page 3, remark
    public void validatePage3Form(Object target, Errors errors) {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "remark",
            "required.remark", "Field name is required.");
    }

    @Override
    public void validate(Object target, Errors errors) {
        validatePage1Form(target, errors);
        validatePage2Form(target, errors);
        validatePage3Form(target, errors);
    }
}

File : User.properties - Свойства для хранения сообщения об ошибке

required.userName = Username is required!
required.password = Password is required!
required.remark = Remark is required!

И в контроллере формы мастера (UserController.java) переопределитеvalidatePage(), вызвав валидатор вручную (больше никаких деклараций, таких как простой контроллер формы).

Смотрите обновленную версиюUserController.java.

public class UserController extends AbstractWizardFormController{
    //other methods, see above

    @Override
    protected void validatePage(Object command, Errors errors, int page) {

        UserValidator validator = (UserValidator) getValidator();

        //page is 0-indexed
        switch (page) {
           case 0: //if page 1 , go validate with validatePage1Form
            validator.validatePage1Form(command, errors);
            break;
           case 1: //if page 2 , go validate with validatePage2Form
            validator.validatePage2Form(command, errors);
            break;
           case 2: //if page 3 , go validate with validatePage3Form
            validator.validatePage3Form(command, errors);
            break;
        }
    }
}

В методеvalidatePage() используйте функцию «switch», чтобы определить, какая страница вызывает и связать ее с соответствующим валидатором. Страница находится в 0-проиндексированном.

5. Конфигурация пружины

Объявите контроллер формы мастера (UserController.java), разместите все страницы в правильном порядке и зарегистрируйте валидатор.

    
           
        
        
        Page1Form 
        Page2Form 
        Page3Form 
        
       
       
        
       
       

Note
В свойстве «pages» порядок значений списка используется для определения последовательности страниц в форме мастера.

Смотрите полный пример:



 

    
    
        
       
        
        Page1Form 
        Page2Form 
        Page3Form 
       
       
       
        
       
      

      
      
       
      

      
           
                /WEB-INF/pages/
           
           
                .jsp
           
       

5. Demo

1. WelcomePage.jsp, щелкните ссылку, перейдите кPage1Form.jsp.

SpringMVC-Multipage-Forms-Example1

2. Page1Form.jsp, содержит поле текстового поля «имя пользователя» и 2 кнопки:

  1. Кнопка «Далее» - перейти к Page2Form.jsp.

  2. Кнопка «отмена» - перейти на WelcomePage.jsp

SpringMVC-Multipage-Forms-Example2

Если при отправке формы имя пользователя пусто, отобразите сообщение об ошибке.

SpringMVC-Multipage-Forms-Example2-Error

3. Page2Form.jsp, содержит поле «пароль» и 3 кнопки:

  1. «Предыдущая» кнопка - перейти к Page1Form.jsp.

  2. Кнопка «Далее» - перейти к Page3Form.jsp.

  3. Кнопка «отмена» - перейти на WelcomePage.jsp.

SpringMVC-Multipage-Forms-Example3

4. Page3Form.jsp, содержит поле текстового поля «примечание» и 3 кнопки:

  1. «Предыдущая» кнопка - перейти к Page2Form.jsp.

  2. Кнопка «Готово» - перейти к ResultForm.jsp.

  3. Кнопка «отмена» - перейти на WelcomePage.jsp.

SpringMVC-Multipage-Forms-Example4

5. ResultForm.jsp, отобразить все данные формы.

SpringMVC-Multipage-Forms-Example5

Скачать исходный код