首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Struts1.3.10深入源代码之核心种RequestProcessor类

2012-07-19 
Struts1.3.10深入源代码之核心类RequestProcessor类Struts控制器组件主要包括:ActionServlet组件:充当Stru

Struts1.3.10深入源代码之核心类RequestProcessor类
Struts控制器组件主要包括:
   ActionServlet组件:充当Struts框架的中央控制器。
   RequestProcess组件:充当每个子应用模块的请求处理器。
   Action组件:负责处理一项具体的业务。
对于多应用模块的Struts应用,每个子应用模块都有各自的RequestProcessor实例。在ActionServlet的process()方法中,一旦选择了正确的子应用模块,就会调用子应用模块的RequestProcessor实例的process()方法来处理请求。在ActionServlet调用这个方法时,会把当前的request和response对象传给它。
下面是RequestProcessor类的源代码:

package org.apache.struts.action;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.apache.struts.Globals;import org.apache.struts.config.ActionConfig;import org.apache.struts.config.ExceptionConfig;import org.apache.struts.config.ForwardConfig;import org.apache.struts.config.ModuleConfig;import org.apache.struts.upload.MultipartRequestWrapper;import org.apache.struts.util.MessageResources;import org.apache.struts.util.RequestUtils;import javax.servlet.RequestDispatcher;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import java.io.IOException;import java.util.HashMap;import java.util.Iterator;import java.util.Locale;public class RequestProcessor {    // ----------------------------------------------------- Manifest Constants    /**     * <p>The request attribute under which the path information is stored for     * processing during a <code>RequestDispatcher.include</code> call.</p>     */    public static final String INCLUDE_PATH_INFO =        "javax.servlet.include.path_info";    /**     * <p>The request attribute under which the servlet path information is     * stored for processing during a <code>RequestDispatcher.include</code>     * call.</p>     */    public static final String INCLUDE_SERVLET_PATH =        "javax.servlet.include.servlet_path";    /**     * <p>Commons Logging instance.</p>     */    protected static Log log = LogFactory.getLog(RequestProcessor.class);    // ----------------------------------------------------- Instance Variables    /**     * <p>The set of <code>Action</code> instances that have been created and     * initialized, keyed by the fully qualified Java class name of the     * <code>Action</code> class.</p>     */    protected HashMap actions = new HashMap();    /**     * <p>The <code>ModuleConfiguration</code> with which we are     * associated.</p>     */    protected ModuleConfig moduleConfig = null;    /**     * <p>The servlet with which we are associated.</p>     */    protected ActionServlet servlet = null;    // --------------------- Public Methods    /**     * <p>Clean up in preparation for a shutdown of this application.</p>     */    public void destroy() {        synchronized (this.actions) {            Iterator actions = this.actions.values().iterator();            while (actions.hasNext()) {                Action action = (Action) actions.next();                action.setServlet(null);            }            this.actions.clear();        }        this.servlet = null;    }    /**     * <p>Initialize this request processor instance.</p>     *     * @param servlet      The ActionServlet we are associated with     * @param moduleConfig The ModuleConfig we are associated with.     * @throws ServletException If an error occor during initialization     */    public void init(ActionServlet servlet, ModuleConfig moduleConfig)        throws ServletException {        synchronized (actions) {            actions.clear();        }        this.servlet = servlet;        this.moduleConfig = moduleConfig;    }    /**     * <p>Process an <code>HttpServletRequest</code> and create the     * corresponding <code>HttpServletResponse</code> or dispatch to another     * resource.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     * @throws IOException      if an input/output error occurs     * @throws 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;        }        this.processCachedMessages(request, response);        // 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;        }        // Process any ActionForm bean related to this request        ActionForm form = processActionForm(request, response, mapping);        processPopulate(request, response, form, mapping);        // Validate any fields of the ActionForm bean, if applicable        try {            if (!processValidate(request, response, form, mapping)) {                return;            }        } catch (InvalidCancelException e) {            ActionForward forward = processException(request, response, e, form, mapping);            processForwardConfig(request, response, forward);            return;        } catch (IOException e) {            throw e;        } catch (ServletException e) {            throw e;        }        // Process a forward or include specified by this mapping        if (!processForward(request, response, mapping)) {            return;        }        if (!processInclude(request, response, mapping)) {            return;        }        // Create or acquire the Action instance to process this request        Action action = processActionCreate(request, response, mapping);        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);    }    // ----------------------------------------------------- Processing Methods    /**     * <p>Return an <code>Action</code> instance that will be used to process     * the current request, creating a new one if necessary.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     * @param mapping  The mapping we are using     * @return An <code>Action</code> instance that will be used to process     *         the current request.     * @throws IOException if an input/output error occurs     */    protected Action processActionCreate(HttpServletRequest request,        HttpServletResponse response, ActionMapping mapping)        throws IOException {        // Acquire the Action instance we will be using (if there is one)        String className = mapping.getType();        if (log.isDebugEnabled()) {            log.debug(" Looking for Action instance for class " + className);        }        // If there were a mapping property indicating whether        // an Action were a singleton or not ([true]),        // could we just instantiate and return a new instance here?        Action instance;        synchronized (actions) {            // Return any existing Action instance of this class            instance = (Action) actions.get(className);            if (instance != null) {                if (log.isTraceEnabled()) {                    log.trace("  Returning existing Action instance");                }                return (instance);            }            // Create and return a new Action instance            if (log.isTraceEnabled()) {                log.trace("  Creating new Action instance");            }            try {                instance = (Action) RequestUtils.applicationInstance(className);                // Maybe we should propagate this exception                // instead of returning null.            } catch (Exception e) {                log.error(getInternal().getMessage("actionCreate",                        mapping.getPath()), e);                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,                    getInternal().getMessage("actionCreate", mapping.getPath()));                return (null);            }            actions.put(className, instance);            if (instance.getServlet() == null) {                instance.setServlet(this.servlet);            }        }        return (instance);    }    /**     * <p>Retrieve and return the <code>ActionForm</code> associated with this     * mapping, creating and retaining one if necessary. If there is no     * <code>ActionForm</code> associated with this mapping, return     * <code>null</code>.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     * @param mapping  The mapping we are using     * @return The <code>ActionForm</code> associated with this mapping.     */    protected ActionForm processActionForm(HttpServletRequest request,        HttpServletResponse response, ActionMapping mapping) {        // Create (if necessary) a form bean to use        ActionForm instance =            RequestUtils.createActionForm(request, mapping, moduleConfig,                servlet);        if (instance == null) {            return (null);        }        // Store the new instance in the appropriate scope        if (log.isDebugEnabled()) {            log.debug(" Storing ActionForm bean instance in scope '"                + mapping.getScope() + "' under attribute key '"                + mapping.getAttribute() + "'");        }        if ("request".equals(mapping.getScope())) {            request.setAttribute(mapping.getAttribute(), instance);        } else {            HttpSession session = request.getSession();            session.setAttribute(mapping.getAttribute(), instance);        }        return (instance);    }    /**     * <p>Forward or redirect to the specified destination, by the specified     * mechanism.  This method uses a <code>ForwardConfig</code> object     * instead an <code>ActionForward</code>.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     * @param forward  The ForwardConfig controlling where we go next     * @throws IOException      if an input/output error occurs     * @throws ServletException if a servlet exception occurs     */    protected void processForwardConfig(HttpServletRequest request,        HttpServletResponse response, ForwardConfig forward)        throws IOException, ServletException {        if (forward == null) {            return;        }        if (log.isDebugEnabled()) {            log.debug("processForwardConfig(" + forward + ")");        }        String forwardPath = forward.getPath();        String uri;        // If the forward can be unaliased into an action, then use the path of the action        String actionIdPath = RequestUtils.actionIdURL(forward, request, servlet);        if (actionIdPath != null) {            forwardPath = actionIdPath;            ForwardConfig actionIdForward = new ForwardConfig(forward);            actionIdForward.setPath(actionIdPath);            forward = actionIdForward;        }        // paths not starting with / should be passed through without any        // processing (ie. they're absolute)        if (forwardPath.startsWith("/")) {            // get module relative uri            uri = RequestUtils.forwardURL(request, forward, null);        } else {            uri = forwardPath;        }        if (forward.getRedirect()) {            // only prepend context path for relative uri            if (uri.startsWith("/")) {                uri = request.getContextPath() + uri;            }            response.sendRedirect(response.encodeRedirectURL(uri));        } else {            doForward(uri, request, response);        }    }    // :FIXME: if Action.execute throws Exception, and Action.process has been    // removed, should the process* methods still throw IOException,    // ServletException?    /**     * <P>Ask the specified <code>Action</code> instance to handle this     * request. Return the <code>ActionForward</code> instance (if any)     * returned by the called <code>Action</code> for further processing.     * </P>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     * @param action   The Action instance to be used     * @param form     The ActionForm instance to pass to this Action     * @param mapping  The ActionMapping instance to pass to this Action     * @return The <code>ActionForward</code> instance (if any) returned by     *         the called <code>Action</code>.     * @throws IOException      if an input/output error occurs     * @throws ServletException if a servlet exception occurs     */    protected ActionForward processActionPerform(HttpServletRequest request,        HttpServletResponse response, Action action, ActionForm form,        ActionMapping mapping)        throws IOException, ServletException {        try {            return (action.execute(mapping, form, request, response));        } catch (Exception e) {            return (processException(request, response, e, form, mapping));        }    }    /**     * <p>Removes any <code>ActionMessages</code> object stored in the session     * under <code>Globals.MESSAGE_KEY</code> and <code>Globals.ERROR_KEY</code>     * if the messages' <code>isAccessed</code> method returns true.  This     * allows messages to be stored in the session, display one time, and be     * released here.</p>     *     * @param request  The servlet request we are processing.     * @param response The servlet response we are creating.     * @since Struts 1.2     */    protected void processCachedMessages(HttpServletRequest request,        HttpServletResponse response) {        HttpSession session = request.getSession(false);        if (session == null) {            return;        }        // Remove messages as needed        ActionMessages messages =            (ActionMessages) session.getAttribute(Globals.MESSAGE_KEY);        if (messages != null) {            if (messages.isAccessed()) {                session.removeAttribute(Globals.MESSAGE_KEY);            }        }        // Remove error messages as needed        messages = (ActionMessages) session.getAttribute(Globals.ERROR_KEY);        if (messages != null) {            if (messages.isAccessed()) {                session.removeAttribute(Globals.ERROR_KEY);            }        }    }    /**     * <p>Set the default content type (with optional character encoding) for     * all responses if requested.  <strong>NOTE</strong> - This header will     * be overridden automatically if a <code>RequestDispatcher.forward</code>     * call is ultimately invoked.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     */    protected void processContent(HttpServletRequest request,        HttpServletResponse response) {        String contentType =            moduleConfig.getControllerConfig().getContentType();        if (contentType != null) {            response.setContentType(contentType);        }    }    /**     * <p>Ask our exception handler to handle the exception. Return the     * <code>ActionForward</code> instance (if any) returned by the called     * <code>ExceptionHandler</code>.</p>     *     * @param request   The servlet request we are processing     * @param response  The servlet response we are processing     * @param exception The exception being handled     * @param form      The ActionForm we are processing     * @param mapping   The ActionMapping we are using     * @return The <code>ActionForward</code> instance (if any) returned by     *         the called <code>ExceptionHandler</code>.     * @throws IOException      if an input/output error occurs     * @throws ServletException if a servlet exception occurs     */    protected ActionForward processException(HttpServletRequest request,        HttpServletResponse response, Exception exception, ActionForm form,        ActionMapping mapping)        throws IOException, ServletException {        // Is there a defined handler for this exception?        ExceptionConfig config = mapping.findException(exception.getClass());        if (config == null) {            log.warn(getInternal().getMessage("unhandledException",                    exception.getClass()));            if (exception instanceof IOException) {                throw (IOException) exception;            } else if (exception instanceof ServletException) {                throw (ServletException) exception;            } else {                throw new ServletException(exception);            }        }        // Use the configured exception handling        try {            ExceptionHandler handler =                (ExceptionHandler) RequestUtils.applicationInstance(config                    .getHandler());            return (handler.execute(exception, config, mapping, form, request,                response));        } catch (Exception e) {            throw new ServletException(e);        }    }    /**     * <p>Process a forward requested by this mapping (if any). Return     * <code>true</code> if standard processing should continue, or     * <code>false</code> if we have already handled this request.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     * @param mapping  The ActionMapping we are using     * @return <code>true</code> to continue normal processing;     *         <code>false</code> if a response has been created.     * @throws IOException      if an input/output error occurs     * @throws ServletException if a servlet exception occurs     */    protected boolean processForward(HttpServletRequest request,        HttpServletResponse response, ActionMapping mapping)        throws IOException, ServletException {        // Are we going to processing this request?        String forward = mapping.getForward();        if (forward == null) {            return (true);        }        // If the forward can be unaliased into an action, then use the path of the action        String actionIdPath = RequestUtils.actionIdURL(forward, this.moduleConfig, this.servlet);        if (actionIdPath != null) {            forward = actionIdPath;        }        internalModuleRelativeForward(forward, request, response);        return (false);    }    /**     * <p>Process an include requested by this mapping (if any). Return     * <code>true</code> if standard processing should continue, or     * <code>false</code> if we have already handled this request.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     * @param mapping  The ActionMapping we are using     * @return <code>true</code> to continue normal processing;     *         <code>false</code> if a response has been created.     * @throws IOException      if an input/output error occurs     * @throws ServletException if thrown by invoked methods     */    protected boolean processInclude(HttpServletRequest request,        HttpServletResponse response, ActionMapping mapping)        throws IOException, ServletException {        // Are we going to processing this request?        String include = mapping.getInclude();        if (include == null) {            return (true);        }        // If the forward can be unaliased into an action, then use the path of the action        String actionIdPath = RequestUtils.actionIdURL(include, this.moduleConfig, this.servlet);        if (actionIdPath != null) {            include = actionIdPath;        }        internalModuleRelativeInclude(include, request, response);        return (false);    }    /**     * <p>Automatically select a <code>Locale</code> for the current user, if     * requested. <strong>NOTE</strong> - configuring Locale selection will     * trigger the creation of a new <code>HttpSession</code> if     * necessary.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     */    protected void processLocale(HttpServletRequest request,        HttpServletResponse response) {        // Are we configured to select the Locale automatically?        if (!moduleConfig.getControllerConfig().getLocale()) {            return;        }        // Has a Locale already been selected?        HttpSession session = request.getSession();        if (session.getAttribute(Globals.LOCALE_KEY) != null) {            return;        }        // Use the Locale returned by the servlet container (if any)        Locale locale = request.getLocale();        if (locale != null) {            if (log.isDebugEnabled()) {                log.debug(" Setting user locale '" + locale + "'");            }            session.setAttribute(Globals.LOCALE_KEY, locale);        }    }    /**     * <p>Select the mapping used to process the selection path for this     * request. If no mapping can be identified, create an error response and     * return <code>null</code>.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     * @param path     The portion of the request URI for selecting a mapping     * @return The mapping used to process the selection path for this     *         request.     * @throws IOException if an input/output error occurs     */    protected ActionMapping processMapping(HttpServletRequest request,        HttpServletResponse response, String path)        throws IOException {        // Is there a mapping for this path?        ActionMapping mapping =            (ActionMapping) moduleConfig.findActionConfig(path);        // If a mapping is found, put it in the request and return it        if (mapping != null) {            request.setAttribute(Globals.MAPPING_KEY, mapping);            return (mapping);        }        // Locate the mapping for unknown paths (if any)        ActionConfig[] configs = moduleConfig.findActionConfigs();        for (int i = 0; i < configs.length; i++) {            if (configs[i].getUnknown()) {                mapping = (ActionMapping) configs[i];                request.setAttribute(Globals.MAPPING_KEY, mapping);                return (mapping);            }        }        // No mapping can be found to process this request        String msg = getInternal().getMessage("processInvalid");        log.error(msg + " " + path);        response.sendError(HttpServletResponse.SC_NOT_FOUND, msg);        return null;    }    /**     * <p>If this is a multipart request, wrap it with a special wrapper.     * Otherwise, return the request unchanged.</p>     *     * @param request The HttpServletRequest we are processing     * @return A wrapped request, if the request is multipart; otherwise the     *         original request.     */    protected HttpServletRequest processMultipart(HttpServletRequest request) {        if (!"POST".equalsIgnoreCase(request.getMethod())) {            return (request);        }        String contentType = request.getContentType();        if ((contentType != null)            && contentType.startsWith("multipart/form-data")) {            return (new MultipartRequestWrapper(request));        } else {            return (request);        }    }    /**     * <p>Set the no-cache headers for all responses, if requested.     * <strong>NOTE</strong> - This header will be overridden automatically if     * a <code>RequestDispatcher.forward</code> call is ultimately     * invoked.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     */    protected void processNoCache(HttpServletRequest request,        HttpServletResponse response) {        if (moduleConfig.getControllerConfig().getNocache()) {            response.setHeader("Pragma", "No-cache");            response.setHeader("Cache-Control", "no-cache,no-store,max-age=0");            response.setDateHeader("Expires", 1);        }    }    /**     * <p>Identify and return the path component (from the request URI) that     * we will use to select an <code>ActionMapping</code> with which to     * dispatch. If no such path can be identified, create an error response     * and return <code>null</code>.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     * @return The path that will be used to select an action mapping.     * @throws IOException if an input/output error occurs     */    protected String processPath(HttpServletRequest request,        HttpServletResponse response)        throws IOException {        String path;        // Set per request the original path for postback forms        if (request.getAttribute(Globals.ORIGINAL_URI_KEY) == null) {            request.setAttribute(Globals.ORIGINAL_URI_KEY, request.getServletPath());        }        // For prefix matching, match on the path info (if any)        path = (String) request.getAttribute(INCLUDE_PATH_INFO);        if (path == null) {            path = request.getPathInfo();        }        if ((path != null) && (path.length() > 0)) {            return (path);        }        // For extension matching, strip the module prefix and extension        path = (String) request.getAttribute(INCLUDE_SERVLET_PATH);        if (path == null) {            path = request.getServletPath();        }        String prefix = moduleConfig.getPrefix();        if (!path.startsWith(prefix)) {            String msg = getInternal().getMessage("processPath");            log.error(msg + " " + request.getRequestURI());            response.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);            return null;        }        path = path.substring(prefix.length());        int slash = path.lastIndexOf("/");        int period = path.lastIndexOf(".");        if ((period >= 0) && (period > slash)) {            path = path.substring(0, period);        }        return (path);    }    /**     * <p>Populate the properties of the specified <code>ActionForm</code>     * instance from the request parameters included with this request.  In     * addition, request attribute <code>Globals.CANCEL_KEY</code> will be set     * if the request was submitted with a button created by     * <code>CancelTag</code>.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     * @param form     The ActionForm instance we are populating     * @param mapping  The ActionMapping we are using     * @throws ServletException if thrown by RequestUtils.populate()     */    protected void processPopulate(HttpServletRequest request,        HttpServletResponse response, ActionForm form, ActionMapping mapping)        throws ServletException {        if (form == null) {            return;        }        // Populate the bean properties of this ActionForm instance        if (log.isDebugEnabled()) {            log.debug(" Populating bean properties from this request");        }        form.setServlet(this.servlet);        form.reset(mapping, request);        if (mapping.getMultipartClass() != null) {            request.setAttribute(Globals.MULTIPART_KEY,                mapping.getMultipartClass());        }        RequestUtils.populate(form, mapping.getPrefix(), mapping.getSuffix(),            request);        // Set the cancellation request attribute if appropriate        if ((request.getParameter(Globals.CANCEL_PROPERTY) != null)            || (request.getParameter(Globals.CANCEL_PROPERTY_X) != null)) {            request.setAttribute(Globals.CANCEL_KEY, Boolean.TRUE);        }    }    /**     * <p>General-purpose preprocessing hook that can be overridden as     * required by subclasses. Return <code>true</code> if you want standard     * processing to continue, or <code>false</code> if the response has     * already been completed. The default implementation does nothing.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     * @return <code>true</code> to continue normal processing;     *         <code>false</code> if a response has been created.     */    protected boolean processPreprocess(HttpServletRequest request,        HttpServletResponse response) {        return (true);    }    /**     * <p>If this action is protected by security roles, make sure that the     * current user possesses at least one of them.  Return <code>true</code>     * to continue normal processing, or <code>false</code> if an appropriate     * response has been created and processing should terminate.</p>     *     * @param request  The servlet request we are processing     * @param response The servlet response we are creating     * @param mapping  The mapping we are using     * @return <code>true</code> to continue normal processing;     *         <code>false</code> if a response has been created.     * @throws IOException      if an input/output error occurs     * @throws ServletException if a servlet exception occurs     */    protected boolean processRoles(HttpServletRequest request,        HttpServletResponse response, ActionMapping mapping)        throws IOException, ServletException {        // Is this action protected by role requirements?        String[] roles = mapping.getRoleNames();        if ((roles == null) || (roles.length < 1)) {            return (true);        }        // Check the current user against the list of required roles        for (int i = 0; i < roles.length; i++) {            if (request.isUserInRole(roles[i])) {                if (log.isDebugEnabled()) {                    log.debug(" User '" + request.getRemoteUser()                        + "' has role '" + roles[i] + "', granting access");                }                return (true);            }        }        // The current user is not authorized for this action        if (log.isDebugEnabled()) {            log.debug(" User '" + request.getRemoteUser()                + "' does not have any required role, denying access");        }        response.sendError(HttpServletResponse.SC_FORBIDDEN,            getInternal().getMessage("notAuthorized", mapping.getPath()));        return (false);    }    /**     * <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 to the input path 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 form     The ActionForm instance we are populating     * @param mapping  The ActionMapping we are using     * @return <code>true</code> to continue normal processing;     *         <code>false</code> if a response has been created.     * @throws IOException      if an input/output error occurs     * @throws ServletException if a servlet exception occurs     * @throws InvalidCancelException if a cancellation is attempted     *         without the proper action configuration.     */    protected boolean processValidate(HttpServletRequest request,        HttpServletResponse response, ActionForm form, ActionMapping mapping)        throws IOException, ServletException, InvalidCancelException {        if (form == null) {            return (true);        }        // Has validation been turned off for this mapping?        if (!mapping.getValidate()) {            return (true);        }        // Was this request cancelled? If it has been, the mapping also        // needs to state whether the cancellation is permissable; otherwise        // the cancellation is considered to be a symptom of a programmer        // error or a spoof.        if (request.getAttribute(Globals.CANCEL_KEY) != null) {            if (mapping.getCancellable()) {                if (log.isDebugEnabled()) {                    log.debug(" Cancelled transaction, skipping validation");                }                return (true);            } else {                request.removeAttribute(Globals.CANCEL_KEY);                throw new InvalidCancelException();            }        }        // Call the form bean's validation method        if (log.isDebugEnabled()) {            log.debug(" Validating input form properties");        }        ActionMessages errors = form.validate(mapping, request);        if ((errors == null) || errors.isEmpty()) {            if (log.isTraceEnabled()) {                log.trace("  No errors detected, accepting input");            }            return (true);        }        // Special handling for multipart request        if (form.getMultipartRequestHandler() != null) {            if (log.isTraceEnabled()) {                log.trace("  Rolling back multipart request");            }            form.getMultipartRequestHandler().rollback();        }        // Was an input path (or forward) 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);    }    /**     * <p>Do a module relative forward to specified URI using request     * dispatcher. URI is relative to the current module. The real URI is     * compute by prefixing the module name.</p> <p>This method is used     * internally and is not part of the public API. It is advised to not use     * it in subclasses. </p>     *     * @param uri      Module-relative URI to forward to     * @param request  Current page request     * @param response Current page response     * @throws IOException      if an input/output error occurs     * @throws ServletException if a servlet exception occurs     * @since Struts 1.1     */    protected void internalModuleRelativeForward(String uri,        HttpServletRequest request, HttpServletResponse response)        throws IOException, ServletException {        // Construct a request dispatcher for the specified path        uri = moduleConfig.getPrefix() + uri;        // Delegate the processing of this request        // :FIXME: - exception handling?        if (log.isDebugEnabled()) {            log.debug(" Delegating via forward to '" + uri + "'");        }        doForward(uri, request, response);    }    /**     * <p>Do a module relative include to specified URI using request     * dispatcher. URI is relative to the current module. The real URI is     * compute by prefixing the module name.</p> <p>This method is used     * internally and is not part of the public API. It is advised to not use     * it in subclasses.</p>     *     * @param uri      Module-relative URI to include     * @param request  Current page request     * @param response Current page response     * @throws IOException      if an input/output error occurs     * @throws ServletException if a servlet exception occurs     * @since Struts 1.1     */    protected void internalModuleRelativeInclude(String uri,        HttpServletRequest request, HttpServletResponse response)        throws IOException, ServletException {        // Construct a request dispatcher for the specified path        uri = moduleConfig.getPrefix() + uri;        // Delegate the processing of this request        // FIXME - exception handling?        if (log.isDebugEnabled()) {            log.debug(" Delegating via include to '" + uri + "'");        }        doInclude(uri, request, response);    }    /**     * <p>Do a forward to specified URI using a <code>RequestDispatcher</code>.     * This method is used by all internal method needing to do a     * forward.</p>     *     * @param uri      Context-relative URI to forward to     * @param request  Current page request     * @param response Current page response     * @throws IOException      if an input/output error occurs     * @throws ServletException if a servlet exception occurs     * @since Struts 1.1     */    protected void doForward(String uri, HttpServletRequest request,        HttpServletResponse response)        throws IOException, ServletException {        RequestDispatcher rd = getServletContext().getRequestDispatcher(uri);        if (rd == null) {            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,                getInternal().getMessage("requestDispatcher", uri));            return;        }        rd.forward(request, response);    }    /**     * <p>Do an include of specified URI using a <code>RequestDispatcher</code>.     * This method is used by all internal method needing to do an     * include.</p>     *     * @param uri      Context-relative URI to include     * @param request  Current page request     * @param response Current page response     * @throws IOException      if an input/output error occurs     * @throws ServletException if a servlet exception occurs     * @since Struts 1.1     */    protected void doInclude(String uri, HttpServletRequest request,        HttpServletResponse response)        throws IOException, ServletException {        RequestDispatcher rd = getServletContext().getRequestDispatcher(uri);        if (rd == null) {            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,                getInternal().getMessage("requestDispatcher", uri));            return;        }        rd.include(request, response);    }    // -------------------- Support Methods    /**     * <p>Return the <code>MessageResources</code> instance containing our     * internal message strings.</p>     *     * @return The <code>MessageResources</code> instance containing our     *         internal message strings.     */    protected MessageResources getInternal() {        return (servlet.getInternal());    }    /**     * <p>Return the <code>ServletContext</code> for the web application in     * which we are running.</p>     *     * @return The <code>ServletContext</code> for the web application.     */    protected ServletContext getServletContext() {        return (servlet.getServletContext());    }}

热点排行