📄 abstractformcontroller.java
字号:
* submitted.
* <p>If you need to have per-form, per-session state management (that is,
* stateful web conversations), the recommendation is to use
* <a href="http://www.springframework.org/webflow">Spring WebFlow</a>,
* which has full support for conversations and has a much more flexible
* usage model overall.
* @param sessionForm <code>true</code> if session form mode is to be activated
*/
public final void setSessionForm(boolean sessionForm) {
this.sessionForm = sessionForm;
}
/**
* Return <code>true</code> if session form mode is activated.
*/
public final boolean isSessionForm() {
return this.sessionForm;
}
/**
* Handles two cases: form submissions and showing a new form.
* Delegates the decision between the two to {@link #isFormSubmission},
* always treating requests without existing form session attribute
* as new form when using session form mode.
* @see #isFormSubmission
* @see #showNewForm
* @see #processFormSubmission
*/
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// Form submission or new form to show?
if (isFormSubmission(request)) {
// Fetch form object from HTTP session, bind, validate, process submission.
try {
Object command = getCommand(request);
ServletRequestDataBinder binder = bindAndValidate(request, command);
BindException errors = new BindException(binder.getBindingResult());
return processFormSubmission(request, response, command, errors);
}
catch (HttpSessionRequiredException ex) {
// Cannot submit a session form if no form object is in the session.
if (logger.isDebugEnabled()) {
logger.debug("Invalid submit detected: " + ex.getMessage());
}
return handleInvalidSubmit(request, response);
}
}
else {
// New form to show: render form view.
return showNewForm(request, response);
}
}
/**
* Determine if the given request represents a form submission.
* <p>The 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());
}
/**
* Return the name of the HttpSession attribute that holds the form object
* for this form controller.
* <p>The default implementation delegates to the {@link #getFormSessionAttributeName()}
* variant without arguments.
* @param request current HTTP request
* @return the name of the form session attribute, or <code>null</code> if not in session form mode
* @see #getFormSessionAttributeName
* @see javax.servlet.http.HttpSession#getAttribute
*/
protected String getFormSessionAttributeName(HttpServletRequest request) {
return getFormSessionAttributeName();
}
/**
* Return the name of the HttpSession attribute that holds the form object
* for this form controller.
* <p>Default is an internal name, of no relevance to applications, as the form
* session attribute is not usually accessed directly. Can be overridden to use
* an application-specific attribute name, which allows other code to access
* the session attribute directly.
* @return the name of the form session attribute
* @see javax.servlet.http.HttpSession#getAttribute
*/
protected String getFormSessionAttributeName() {
return getClass().getName() + ".FORM." + getCommandName();
}
/**
* 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
* @see #getErrorsForNewForm
*/
protected final ModelAndView showNewForm(HttpServletRequest request, HttpServletResponse response)
throws Exception {
logger.debug("Displaying new form");
return showForm(request, response, getErrorsForNewForm(request));
}
/**
* Create a BindException instance for a new form.
* Called by {@link #showNewForm}.
* <p>Can be used directly when intending to show a new form but with
* special errors registered on it (for example, on invalid submit).
* Usually, the resulting BindException will be passed to
* {@link #showForm(HttpServletRequest, HttpServletResponse, BindException)},
* after registering the errors on it.
* @param request current HTTP request
* @return the BindException instance
* @throws Exception in case of an invalid new form object
* @see #showNewForm
* @see #showForm(HttpServletRequest, HttpServletResponse, BindException)
* @see #handleInvalidSubmit
*/
protected final BindException getErrorsForNewForm(HttpServletRequest request) throws Exception {
// Create form-backing object for new form.
Object command = formBackingObject(request);
if (command == null) {
throw new ServletException("Form object returned by formBackingObject() must not be null");
}
if (!checkCommand(command)) {
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, command);
BindException errors = new BindException(binder.getBindingResult());
if (isBindOnNewForm()) {
logger.debug("Binding to new form");
binder.bind(request);
onBindOnNewForm(request, command, errors);
}
// Return BindException object that resulted from binding.
return errors;
}
/**
* Callback for custom post-processing in terms of binding for a new form.
* Called when preparing a new form if <code>bindOnNewForm</code> is <code>true</code>.
* <p>The default implementation delegates to <code>onBindOnNewForm(request, command)</code>.
* @param request current HTTP request
* @param command the command object to perform further binding on
* @param errors validation errors holder, allowing for additional
* custom registration of binding errors
* @throws Exception in case of invalid state or arguments
* @see #onBindOnNewForm(javax.servlet.http.HttpServletRequest, Object)
* @see #setBindOnNewForm
*/
protected void onBindOnNewForm(HttpServletRequest request, Object command, BindException errors)
throws Exception {
onBindOnNewForm(request, command);
}
/**
* Callback for custom post-processing in terms of binding for a new form.
* <p>Called by the default implementation of the
* {@link #onBindOnNewForm(HttpServletRequest, Object, BindException)} variant
* with all parameters, after standard binding when displaying the form view.
* Only called if <code>bindOnNewForm</code> is set to <code>true</code>.
* <p>The default implementation is empty.
* @param request current HTTP request
* @param command the command object to perform further binding on
* @throws Exception in case of invalid state or arguments
* @see #onBindOnNewForm(HttpServletRequest, Object, BindException)
* @see #setBindOnNewForm(boolean)
*/
protected void onBindOnNewForm(HttpServletRequest request, Object command) throws Exception {
}
/**
* Return the form object for the given request.
* <p>Calls {@link #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 org.springframework.web.HttpSessionRequiredException
* if a session was expected but no active session (or session form object) found
* @throws Exception in case of invalid state or arguments
* @see #formBackingObject
*/
protected final Object getCommand(HttpServletRequest request) throws Exception {
// If not in session-form mode, create a new form-backing object.
if (!isSessionForm()) {
return formBackingObject(request);
}
// Session-form mode: retrieve form object from HTTP session attribute.
HttpSession session = request.getSession(false);
if (session == null) {
throw new HttpSessionRequiredException("Must have session when trying to bind (in session-form mode)");
}
String formAttrName = getFormSessionAttributeName(request);
Object sessionFormObject = session.getAttribute(formAttrName);
if (sessionFormObject == null) {
throw new HttpSessionRequiredException("Form object not found in session (in session-form mode)");
}
// Remove form object from HTTP session: we might finish the form workflow
// in this request. If it turns out that we need to show the form view again,
// we'll re-bind the form object to the HTTP session.
if (logger.isDebugEnabled()) {
logger.debug("Removing form session attribute [" + formAttrName + "]");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -