📄 abstractformcontroller.java
字号:
// process submit
Object command = getCommand(request);
ServletRequestDataBinder binder = bindAndValidate(request, command);
return processFormSubmission(request, response, command, binder.getErrors());
}
else {
return showNewForm(request, response);
}
}
/**
* Determine if the given request represents a form submission.
* <p>Default implementation treats a POST request as form submission.
* Note: If the form session attribute doesn't exist when using session form
* mode, the request is always treated as new form by handleRequestInternal.
* <p>Subclasses can override this to use a custom strategy, e.g. a specific
* request parameter (assumably a hidden field or submit button name).
* @param request current HTTP request
* @return if the request represents a form submission
*/
protected boolean isFormSubmission(HttpServletRequest request) {
return "POST".equals(request.getMethod());
}
/**
* Show a new form. Prepares a backing object for the current form
* and the given request, including checking its validity.
* @param request current HTTP request
* @param response current HTTP response
* @return the prepared form view
* @throws Exception in case of an invalid new form object
*/
protected final ModelAndView showNewForm(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// show new form
logger.debug("Displaying new form");
Object formObject = formBackingObject(request);
if (formObject == null) {
throw new ServletException("Form object returned by formBackingObject() may not be null");
}
if (!checkCommand(formObject)) {
throw new ServletException("Form object returned by formBackingObject() must match commandClass");
}
// bind without validation, to allow for prepopulating a form, and for
// convenient error evaluation in views (on both first attempt and resubmit)
ServletRequestDataBinder binder = createBinder(request, formObject);
if (isBindOnNewForm()) {
logger.debug("Binding to new form");
binder.bind(request);
}
return showForm(request, response, binder.getErrors());
}
/**
* Retrieve a backing object for the current form from the given request.
* <p>The properties of the form object will correspond to the form field values
* in your form view. This object will be exposed in the model under the specified
* command name, to be accessed under that name in the view: for example, with
* a "spring:bind" tag. The default command name is "command".
* <p>Note that you need to activate session form mode to reuse the form-backing
* object across the entire form workflow. Else, a new instance of the command
* class will be created for each submission attempt, just using this backing
* object as template for the initial form.
* <p>Default implementation calls BaseCommandController.createCommand,
* creating a new empty instance of the command class.
* Subclasses can override this to provide a preinitialized backing object.
* @param request current HTTP request
* @return the backing objact
* @throws Exception in case of invalid state or arguments
* @see #setCommandName
* @see #setCommandClass
* @see #createCommand
*/
protected Object formBackingObject(HttpServletRequest request) throws Exception {
return createCommand();
}
/**
* Prepare the form model and view, including reference and error data.
* Can show a configured form page, or generate a programmatic form view.
* <p>A typical implementation will call showForm(request,errors,"myView")
* to prepare the form view for a specific view name.
* <p>Note: If you decide to have a "formView" property specifying the
* view name, consider using SimpleFormController.
* @param request current HTTP request
* @param response current HTTP response
* @param errors validation errors holder
* @return the prepared form view, or null if handled directly
* @throws Exception in case of invalid state or arguments
* @see #showForm(HttpServletRequest, BindException, String)
* @see SimpleFormController#setFormView
*/
protected abstract ModelAndView showForm(HttpServletRequest request, HttpServletResponse response,
BindException errors) throws Exception;
/**
* Prepare model and view for the given form, including reference and errors.
* In session form mode: Re-puts the form object in the session when returning
* to the form, as it has been removed by getCommand.
* Can be used in subclasses to redirect back to a specific form page.
* @param request current HTTP request
* @param errors validation errors holder
* @param viewName name of the form view
* @return the prepared form view
* @throws Exception in case of invalid state or arguments
*/
protected final ModelAndView showForm(HttpServletRequest request, BindException errors, String viewName)
throws Exception {
return showForm(request, errors, viewName, null);
}
/**
* Prepare model and view for the given form, including reference and errors,
* adding a controller-specific control model.
* In session form mode: Re-puts the form object in the session when returning
* to the form, as it has been removed by getCommand.
* Can be used in subclasses to redirect back to a specific form page.
* @param request current HTTP request
* @param errors validation errors holder
* @param viewName name of the form view
* @param controlModel model map containing controller-specific control data
* (e.g. current page in wizard-style controllers).
* @return the prepared form view
* @throws Exception in case of invalid state or arguments
*/
protected final ModelAndView showForm(HttpServletRequest request, BindException errors, String viewName,
Map controlModel) throws Exception {
if (isSessionForm()) {
request.getSession().setAttribute(getFormSessionAttributeName(), errors.getTarget());
}
Map model = errors.getModel();
Map referenceData = referenceData(request, errors.getTarget(), errors);
if (referenceData != null) {
model.putAll(referenceData);
}
if (controlModel != null) {
model.putAll(controlModel);
}
return new ModelAndView(viewName, model);
}
/**
* Create a reference data map for the given request, consisting of
* bean name/bean instance pairs as expected by ModelAndView.
* <p>Default implementation returns null.
* Subclasses can override this to set reference data used in the view.
* @param request current HTTP request
* @param command form object with request parameters bound onto it
* @param errors validation errors holder
* @return a Map with reference data entries, or null if none
* @throws Exception in case of invalid state or arguments
* @see ModelAndView
*/
protected Map referenceData(HttpServletRequest request, Object command, Errors errors) throws Exception {
return null;
}
/**
* Handle an invalid submit request, e.g. when in session form mode but no form object
* was found in the session (like in case of an invalid resubmit by the browser).
* <p>Default implementation simply tries to resubmit the form with a new form object.
* This should also work if the user hit the back button, changed some form data,
* and resubmitted the form.
* <p>Note: To avoid duplicate submissions, you need to override this method.
* Either show some "invalid submit" message, or call showNewForm for resetting the
* form (prepopulating it with the current values if "bindOnNewForm" is true).
* In this case, the form object in the session serves as transaction token.
* @param request current HTTP request
* @param response current HTTP response
* @return a prepared view, or null if handled directly
* @throws Exception in case of errors
* @see #showNewForm
* @see #setBindOnNewForm
*/
protected ModelAndView handleInvalidSubmit(HttpServletRequest request, HttpServletResponse response)
throws Exception {
Object command = formBackingObject(request);
ServletRequestDataBinder binder = bindAndValidate(request, command);
return processFormSubmission(request, response, command, binder.getErrors());
}
/**
* Return the form object for the given request.
* <p>Calls formBackingObject if not in session form mode. Else, retrieves the
* form object from the session. Note that the form object gets removed from
* the session, but it will be re-added when showing the form for resubmission.
* @param request current HTTP request
* @return object form to bind onto
* @throws Exception in case of invalid state or arguments
* @see #formBackingObject
*/
protected final Object getCommand(HttpServletRequest request) throws Exception {
if (!isSessionForm()) {
return formBackingObject(request);
}
HttpSession session = request.getSession(false);
if (session == null) {
throw new ServletException("Must have session when trying to bind");
}
Object formObject = session.getAttribute(getFormSessionAttributeName());
session.removeAttribute(getFormSessionAttributeName());
if (formObject == null) {
throw new ServletException("Form object not found in session");
}
return formObject;
}
/**
* Process form submission request. Called by handleRequestInternal in case
* of a form submission.
* <p>Subclasses can override this to provide custom submission handling
* like triggering a custom action. They can also provide custom validation
* and call showForm or proceed with the submission accordingly.
* <p>Can call errors.getModel() to populate the ModelAndView model with the command
* and the Errors instance, under the specified bean name.
* @param request current servlet request
* @param response current servlet response
* @param command form object with request parameters bound onto it
* @param errors holder without errors (subclass can add errors if it wants to)
* @return the prepared model and view, or null
* @throws Exception in case of errors
* @see #isFormSubmission
* @see #showForm
* @see org.springframework.validation.Errors
*/
protected abstract ModelAndView processFormSubmission(HttpServletRequest request, HttpServletResponse response,
Object command, BindException errors)
throws Exception;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -