0,0 → 1,231 |
/** |
* Extends and based on Apache Struts source code. |
* |
* Copyleft Anatoli Klassen (anatoli@aksoft.net) |
*/ |
package ak.strutsx; |
|
|
import java.io.IOException; |
|
import javax.servlet.ServletException; |
import javax.servlet.http.HttpServletRequest; |
import javax.servlet.http.HttpServletResponse; |
|
import org.apache.struts.Globals; |
import org.apache.struts.action.Action; |
import org.apache.struts.action.ActionErrors; |
import org.apache.struts.action.ActionForward; |
import org.apache.struts.action.ActionMapping; |
import org.apache.struts.action.ActionForm; |
import org.apache.struts.action.RequestProcessor; |
import org.apache.struts.config.ForwardConfig; |
|
/** |
* To use this processor add |
* <controller processorClass="ak.strutsx.RequestProcessorX" /> |
* into the struts-config.xml file. |
*/ |
public class RequestProcessorX |
extends RequestProcessor |
{ |
/** |
* <p>Process an <code>HttpServletRequest</code> and create the |
* corresponding <code>HttpServletResponse</code>.</p> |
* |
* @param request The servlet request we are processing |
* @param response The servlet response we are creating |
* |
* @exception IOException if an input/output error occurs |
* @exception ServletException if a processing exception occurs |
*/ |
public void process(HttpServletRequest request, |
HttpServletResponse response) |
throws IOException, ServletException { |
|
// Wrap multipart requests with a special wrapper |
request = processMultipart(request); |
|
// Identify the path component we will use to select a mapping |
String path = processPath(request, response); |
if (path == null) { |
return; |
} |
if (log.isDebugEnabled()) { |
log.debug("Processing a '" + request.getMethod() + |
"' for path '" + path + "'"); |
} |
|
// Select a Locale for the current user if requested |
processLocale(request, response); |
|
// Set the content type and no-caching headers if requested |
processContent(request, response); |
processNoCache(request, response); |
|
// General purpose preprocessing hook |
if (!processPreprocess(request, response)) { |
return; |
} |
|
// Identify the mapping for this request |
ActionMapping mapping = processMapping(request, response, path); |
if (mapping == null) { |
return; |
} |
|
// Check for any role required to perform this action |
if (!processRoles(request, response, mapping)) { |
return; |
} |
|
// Create or acquire the Action instance to process this request |
// Do this here, because we need the action in case form validation is failed |
Action action = null; |
if (mapping.getType() != null) { |
action = processActionCreate(request, response, mapping); |
} |
|
// Process any ActionForm bean related to this request |
ActionForm form = processActionForm(request, response, mapping); |
processPopulate(request, response, form, mapping); |
if (!processValidate(request, response, action, form, mapping)) { |
return; |
} |
|
// Process a forward or include specified by this mapping |
if (!processForward(request, response, mapping)) { |
return; |
} |
if (!processInclude(request, response, mapping)) { |
return; |
} |
|
// no action |
if (action == null) { |
return; |
} |
|
// Call the Action instance itself |
ActionForward forward = |
processActionPerform(request, response, |
action, form, mapping); |
|
// Process the returned ActionForward instance |
processForwardConfig(request, response, forward); |
|
} |
|
/** |
* <p>If this request was not cancelled, and the request's |
* {@link ActionMapping} has not disabled validation, call the |
* <code>validate()</code> method of the specified {@link ActionForm}, |
* and forward back to the input form if there were any errors. |
* Return <code>true</code> if we should continue processing, |
* or <code>false</code> if we have already forwarded control back |
* to the input form.</p> |
* |
* @param request The servlet request we are processing |
* @param response The servlet response we are creating |
* @param action The Action instance we are populating |
* @param form The ActionForm instance we are populating |
* @param mapping The ActionMapping we are using |
* |
* @exception IOException if an input/output error occurs |
* @exception ServletException if a servlet exception occurs |
*/ |
protected boolean processValidate(HttpServletRequest request, |
HttpServletResponse response, |
Action action, |
ActionForm form, |
ActionMapping mapping) |
throws IOException, ServletException { |
|
if (form == null) { |
return (true); |
} |
|
// Was this request cancelled? |
if (request.getAttribute(Globals.CANCEL_KEY) != null) { |
if (log.isDebugEnabled()) { |
log.debug(" Cancelled transaction, skipping validation"); |
} |
return (true); |
} |
|
// Has validation been turned off for this mapping? |
if (!mapping.getValidate()) { |
return (true); |
} |
|
// Call the form bean's validation method |
if (log.isDebugEnabled()) { |
log.debug(" Validating input form properties"); |
} |
ActionErrors errors = form.validate(mapping, request); |
if ((errors == null) || errors.isEmpty()) { |
if (log.isTraceEnabled()) { |
log.trace(" No errors detected, accepting input"); |
} |
return (true); |
} |
|
// Form validation failed, try to inform the action |
if((action != null) && (action instanceof ErrorHandlerX)) { |
processValidationFailed(request, response, |
(ErrorHandlerX)action, form, mapping); |
} |
|
// Special handling for multipart request |
if (form.getMultipartRequestHandler() != null) { |
if (log.isTraceEnabled()) { |
log.trace(" Rolling back multipart request"); |
} |
form.getMultipartRequestHandler().rollback(); |
} |
|
// Has an input form been specified for this mapping? |
String input = mapping.getInput(); |
if (input == null) { |
if (log.isTraceEnabled()) { |
log.trace(" Validation failed but no input form available"); |
} |
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, |
getInternal().getMessage("noInput", |
mapping.getPath())); |
return (false); |
} |
|
// Save our error messages and return to the input form if possible |
if (log.isDebugEnabled()) { |
log.debug(" Validation failed, returning to '" + input + "'"); |
} |
request.setAttribute(Globals.ERROR_KEY, errors); |
|
if (moduleConfig.getControllerConfig().getInputForward()) { |
ForwardConfig forward = mapping.findForward(input); |
processForwardConfig( request, response, forward); |
} else { |
internalModuleRelativeForward(input, request, response); |
} |
|
return (false); |
|
} |
|
protected void |
processValidationFailed(HttpServletRequest request, |
HttpServletResponse response, |
ErrorHandlerX errorHandler, |
ActionForm form, |
ActionMapping mapping) |
throws IOException, ServletException { |
|
try { |
errorHandler.handleErrors(mapping, form, request, response); |
} catch (Exception e) { |
processException(request, response, e, form, mapping); |
} |
|
} |
} |