Process of progressive struts1 (5)

Source: Internet
Author: User

This blog goes deep into the Struts framework to execute some source code. Starting from the actionservlet process function, let's take a look at its internal execution process.

Flowchart

The following flowchart shows the functions used by the actionservlet and requestprocessor classes. For example, the functions of other classes called by requestprocessor are not described.



Function Description

Let's select several important function descriptions, while other functions can be simply described.

Actionservlet Process

    /**     * <p>Perform the standard request processing for this request, and create     * the corresponding response.</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 servlet exception is thrown     */    protected void process(HttpServletRequest request, HttpServletResponse response)        throws IOException, ServletException {        ModuleUtils.getInstance().selectModule(request, getServletContext());        ModuleConfig config = getModuleConfig(request);        RequestProcessor processor = getProcessorForModule(config);        if (processor == null) {           processor = getRequestProcessor(config);        }        processor.process(request, response);    }}

During debugging, you must first enter this function (after Tomcat is started and a request is generated). This function is used to obtain the module object generated in the loading phase and generate the main object requestprocessor for struts logic processing.

Requestprocessor Process

   /**     * <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     *     * @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;        }                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);    }

Process is the main logical processing function of the requestprocessor object. According to the flowchart above, we can see that the entire logical processing is completed in this function. The functions of the called function are as follows:
Processmultipart

This function is used to determine whether it is a file upload request. If it is a file upload request, it is specially processed.

    /**     * <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     */    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);        }    }
Processpath

Obtain and intercept the request. After processing, the request becomes a required string, for example, http: // localhost: 8080/struts_login/login. Do. The processed string is/login. Do.

   /**     * <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     *     * @exception IOException if an input/output error occurs     */    protected String processPath(HttpServletRequest request,                                 HttpServletResponse response)        throws IOException {        String path = null;        // 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);    }
Set related functions

Processlocale, processcontent, processnocache, and processcachedmessages are used to set up international files, set content types, cancel cache settings, and clear struts error information in sessions.

Processmapping

Instantiate the corresponding actionmapping object based on the path generated above. If this object is not empty, it is loaded into the request and the corresponding name is globals. mapping_key. If it is null, an exception is sent and added to response.

        // 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);            }        }
Processroles

Whether action execution requires specific role permissions. If not, continue execution.

        String roles[] = mapping.getRoleNames();        if ((roles == null) || (roles.length < 1)) {            return (true);        }
Processactionform

Create an actionform and check the action scope. If it is a request, it is added to the request. If it is a session, it is added to the session.

       // 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);        }
Actionform Problems

Processpopulate: calls the processpopulate () method. If there is an actionform configured for actionmapping, it encapsulates the data in the request object to actionform.
Before encapsulation, call the reset () method of actionform to set the default attribute values.

Processvalidate: If the attribute validate of the action element is set to true, The Validate () method is called for rule verification. If the validate () method validation fails, an actionerrors
In the request area, the request is automatically redirected to the page specified by the INPUT attribute mapped to the action. If the verification is passed or the actionform is not configured in the Action ing, the request is processed.

Exception Handling

The process function contains a try... Catch Block. If invalidcancelexception occurs, two functions are executed.

Processexception: writes the exception to the Log Warning file and runs out of the exception. processforwardconfig is the same as the last function executed below, and the capture ends.

Jump path

Processforward and processinclude: these two functions are used to check the values of the forward and include attributes of the <action> element in Struts-config. If there is a configuration, forward and include
The request is placed on the configuration page. processforward () calls requestdispatcher. Forward (), while processinclude () calls requestdispatcher. Include ().

If both the forward and include attributes are configured, Struts gives priority to forward.

Processactioncreate

This function obtains the action class name from the type attribute of <action> In Struts-config, and creates and returns its instance.

        Action instance = null;        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);                // :TODO: 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);            }                        instance.setServlet(this.servlet);            actions.put(className, instance);        }        return (instance);

Processactionperform

Execute the Execute function in the Self-written action, including the jump logic:

        try {            return (action.execute(mapping, form, request, response));        } catch (Exception e) {            return (processException(request, response,                                     e, form, mapping));        }

Processforwardconfig:
        String forwardPath = forward.getPath();        String uri = null;                // paths not starting with / should be passed through without any processing        // (ie. they're absolute)        if (forwardPath.startsWith("/")) {            uri = RequestUtils.forwardURL(request, forward, null);    // get module relative uri        } else {            uri = forwardPath;        }
Doforward obtains requestdispatcher and performs a jump.
        if (request instanceof MultipartRequestWrapper) {            request = ((MultipartRequestWrapper) request).getRequest();        }        RequestDispatcher rd = getServletContext().getRequestDispatcher(uri);        if (rd == null) {            response.sendError(                HttpServletResponse.SC_INTERNAL_SERVER_ERROR,                getInternal().getMessage("requestDispatcher", uri));            return;        }        rd.forward(request, response);
Summary

If we ignore the function, we can summarize it from a macro perspective as follows:

  • Read configuration files
  • Get access address
  • Set struts
  • Create, assign, and verify actionform
  • Exception Handling
  • Create action
  • Execute the logic in the action
  • Page Jump

So far, if you do not investigate the underlying function, the struts execution process has been explained. If you have any questions, please note.

For more related blogs, go to the Summary of progressive struts1 (8)


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.