📄 abstractwizardformcontroller.java
字号:
setPageRenderParameter(response, currentPage);
setFinishRenderParameter(request, response);
}
validatePagesAndFinish(request, response, command, errors, currentPage);
return;
}
// Normal submit: validate current page
if (!suppressValidation(request)) {
if (logger.isDebugEnabled()) {
logger.debug("Validating wizard page " + currentPage + " for form bean '" + getCommandName() + "'");
}
validatePage(command, errors, currentPage, false);
}
setPageRenderParameter(response, currentPage);
setTargetRenderParameter(request, response);
passRenderParameters(request, response);
// Give subclasses a change to perform custom post-procession
// of the current page and its command object.
postProcessPage(request, command, errors, currentPage);
}
/**
* Return the current page number. Used by {@link #processFormSubmission}.
* <p>The default implementation checks the page session attribute.
* Subclasses can override this for customized page determination.
* @param request current portlet request
* @return the current page number
* @see #getPageSessionAttributeName()
*/
protected int getCurrentPage(PortletRequest request) {
// Check for overriding attribute in request.
String pageAttrName = getPageSessionAttributeName(request);
Integer pageAttr = (Integer) request.getAttribute(pageAttrName);
if (pageAttr != null) {
return pageAttr.intValue();
}
// Check for explicit request parameter.
String pageParam = request.getParameter(PARAM_PAGE);
if (pageParam != null) {
return Integer.parseInt(pageParam);
}
// Check for original attribute in session.
if (isSessionForm()) {
pageAttr = (Integer) request.getPortletSession().getAttribute(pageAttrName);
if (pageAttr != null) {
return pageAttr.intValue();
}
}
throw new IllegalStateException("Page attribute [" + pageAttrName + "] neither found in session nor in request");
}
/**
* Determine whether the incoming request is a request to finish the
* processing of the current form.
* <p>By default, this method returns <code>true</code> if a parameter
* matching the "_finish" key is present in the request, otherwise it
* returns <code>false</code>. Subclasses may override this method
* to provide custom logic to detect a finish request.
* <p>The parameter is recognized both when sent as a plain parameter
* ("_finish") or when triggered by an image button ("_finish.x").
* @param request current portlet request
* @return whether the request indicates to finish form processing
* @see #PARAM_FINISH
*/
protected boolean isFinishRequest(PortletRequest request) {
return PortletUtils.hasSubmitParameter(request, PARAM_FINISH);
}
/**
* Determine whether the incoming request is a request to cancel the
* processing of the current form.
* <p>By default, this method returns <code>true</code> if a parameter
* matching the "_cancel" key is present in the request, otherwise it
* returns <code>false</code>. Subclasses may override this method
* to provide custom logic to detect a cancel request.
* <p>The parameter is recognized both when sent as a plain parameter
* ("_cancel") or when triggered by an image button ("_cancel.x").
* @param request current portlet request
* @return whether the request indicates to cancel form processing
* @see #PARAM_CANCEL
*/
protected boolean isCancelRequest(PortletRequest request) {
return PortletUtils.hasSubmitParameter(request, PARAM_CANCEL);
}
/**
* Return the target page specified in the request.
* <p>Default implementation delegates to
* <code>getTargetPage(PortletRequest, int)</code>.
* Subclasses can override this for customized target page determination.
* @param request current portlet request
* @param command form object with request parameters bound onto it
* @param errors validation errors holder
* @param currentPage the current page, to be returned as fallback
* if no target page specified
* @return the page specified in the request, or current page if not found
* @see #getTargetPage(PortletRequest, int)
*/
protected int getTargetPage(PortletRequest request, Object command, Errors errors, int currentPage) {
return getTargetPage(request, currentPage);
}
/**
* Return the target page specified in the request.
* <p>Default implementation examines "_target" parameter (e.g. "_target1").
* Subclasses can override this for customized target page determination.
* @param request current portlet request
* @param currentPage the current page, to be returned as fallback
* if no target page specified
* @return the page specified in the request, or current page if not found
* @see #PARAM_TARGET
*/
protected int getTargetPage(PortletRequest request, int currentPage) {
Enumeration paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
String paramName = (String) paramNames.nextElement();
if (paramName.startsWith(PARAM_TARGET)) {
for (int i = 0; i < WebUtils.SUBMIT_IMAGE_SUFFIXES.length; i++) {
String suffix = WebUtils.SUBMIT_IMAGE_SUFFIXES[i];
if (paramName.endsWith(suffix)) {
paramName = paramName.substring(0, paramName.length() - suffix.length());
}
}
return Integer.parseInt(paramName.substring(PARAM_TARGET.length()));
}
}
return currentPage;
}
/**
* Validate all pages and process finish.
* If there are page validation errors, show the corresponding view page.
* @see #validatePagesAndFinish
*/
private ModelAndView renderValidatePagesAndFinish(
RenderRequest request, RenderResponse response, Object command, BindException errors, int currentPage)
throws Exception {
// In case of any errors -> show current page.
if (errors.hasErrors())
return showPage(request, errors, currentPage);
// No remaining errors -> proceed with finish.
return renderFinish(request, response, command, errors);
}
/**
* Validate all pages and process finish.
* If there are page validation errors, show the corresponding view page.
* @see #renderValidatePagesAndFinish
*/
private void validatePagesAndFinish(
ActionRequest request, ActionResponse response, Object command, BindException errors, int currentPage)
throws Exception {
// In case of binding errors -> show current page.
if (errors.hasErrors()) {
setPageRenderParameter(response, currentPage);
passRenderParameters(request, response);
return;
}
if (!suppressValidation(request)) {
// In case of remaining errors on a page -> show the page.
for (int page = 0; page < getPageCount(request, command); page++) {
validatePage(command, errors, page, true);
if (errors.hasErrors()) {
setPageRenderParameter(response, currentPage);
passRenderParameters(request, response);
return;
}
}
}
// No remaining errors -> proceed with finish.
if (!isRedirectAction())
setPageRenderParameter(response, currentPage);
processFinish(request, response, command, errors);
}
/**
* Template method for custom validation logic for individual pages.
* Default implementation calls <code>validatePage(command, errors, page)</code>.
* <p>Implementations will typically call fine-granular <code>validateXXX</code>
* methods of this instance's Validator, combining them to validation of the
* corresponding pages. The Validator's default <code>validate</code> method
* will not be called by a wizard form controller!
* @param command form object with the current wizard state
* @param errors validation errors holder
* @param page number of page to validate
* @param finish whether this method is called during final revalidation on finish
* (else, it is called for validating the current page)
* @see #validatePage(Object, Errors, int)
* @see org.springframework.validation.Validator#validate
*/
protected void validatePage(Object command, Errors errors, int page, boolean finish) {
validatePage(command, errors, page);
}
/**
* Template method for custom validation logic for individual pages.
* Default implementation is empty.
* <p>Implementations will typically call fine-granular validateXXX methods of this
* instance's validator, combining them to validation of the corresponding pages.
* The validator's default <code>validate</code> method will not be called by a
* wizard form controller!
* @param command form object with the current wizard state
* @param errors validation errors holder
* @param page number of page to validate
* @see org.springframework.validation.Validator#validate
*/
protected void validatePage(Object command, Errors errors, int page) {
}
/**
* Post-process the given page after binding and validation, potentially
* updating its command object. The passed-in request might contain special
* parameters sent by the page.
* <p>Only invoked when displaying another page or the same page again,
* not when finishing or cancelling.
* @param request current action request
* @param command form object with request parameters bound onto it
* @param errors validation errors holder
* @param page number of page to post-process
* @throws Exception in case of invalid state or arguments
*/
protected void postProcessPage(ActionRequest request, Object command, Errors errors, int page)
throws Exception {
}
/**
* Template method for the render phase of the finish action of this wizard.
* <p>Default implementation throws a PortletException, saying that a finish
* render request is not supported by this controller. Thus, you do not need to
* implement this template method if you do not need to render after a finish.
* <p>Call <code>errors.getModel()</code> to populate the ModelAndView model
* with the command and the Errors instance, under the specified command name,
* as expected by the "spring:bind" tag.
* @param request current portlet render request
* @param response current portlet render response
* @param command form object with the current wizard state
* @param errors validation errors holder
* @return the finish view
* @throws Exception in case of invalid state or arguments
* @see #processFinish
* @see org.springframework.validation.Errors
* @see org.springframework.validation.BindException#getModel
*/
protected ModelAndView renderFinish(
RenderRequest request, RenderResponse response, Object command, BindException errors)
throws Exception {
throw new PortletException("Wizard form controller class [" + getClass().getName() + "] does not support a finish render request");
}
/**
* Template method for the action phase of the finish action of this wizard.
* <p>Default implementation throws a PortletException, saying that a finish
* action request is not supported by this controller. You will almost certainly
* need to override this method.
* @param request current portlet action request
* @param response current portlet action response
* @param command form object with the current wizard state
* @param errors validation errors holder
* @throws Exception in case of invalid state or arguments
* @see #renderFinish
* @see org.springframework.validation.Errors
*/
protected void processFinish(
ActionRequest request, ActionResponse response, Object command, BindException errors)
throws Exception {
throw new PortletException(
"Wizard form controller class [" + getClass().getName() + "] does not support a finish action request");
}
/**
* Template method for the render phase of the cancel action of this wizard.
* <p>Default implementation throws a PortletException, saying that a cancel
* render request is not supported by this controller. Thus, you do not need to
* implement this template method if you do not support a cancel operation.
* <p>Call <code>errors.getModel()</code> to populate the ModelAndView model
* with the command and the Errors instance, under the specified command name,
* as expected by the "spring:bind" tag.
* @param request current portlet render request
* @param response current portlet render response
* @param command form object with the current wizard state
* @param errors Errors instance containing errors
* @return the cancellation view
* @throws Exception in case of invalid state or arguments
* @see #processCancel
* @see org.springframework.validation.Errors
* @see org.springframework.validation.BindException#getModel
*/
protected ModelAndView renderCancel(
RenderRequest request, RenderResponse response, Object command, BindException errors)
throws Exception {
throw new PortletException(
"Wizard form controller class [" + getClass().getName() + "] does not support a cancel render request");
}
/**
* Template method for the action phase of the cancel action of this wizard.
* <p>Default implementation throws a PortletException, saying that a cancel
* action request is not supported by this controller. Thus, you do not need to
* implement this template method if you do not support a cancel operation.
* @param request current portlet action request
* @param response current portlet action response
* @param command form object with the current wizard state
* @param errors Errors instance containing errors
* @throws Exception in case of invalid state or arguments
* @see #renderCancel
* @see org.springframework.validation.Errors
*/
protected void processCancel(
ActionRequest request, ActionResponse response, Object command, BindException errors)
throws Exception {
throw new PortletException(
"Wizard form controller class [" + getClass().getName() + "] does not support a cancel action request");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -