1. 程式人生 > >struts1原始碼學習6(doPost和doGet)

struts1原始碼學習6(doPost和doGet)

ActionServlet中的doPost和doGet的程式碼是一樣的,都是呼叫process

直接看process程式碼

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

簡單幾行,不過每行都很有貨啊!(否則前面那麼複雜的配置怎麼體現)

1、process第一行程式碼

 ModuleUtils.getInstance().selectModule(request, getServletContext());
ModuleUtils

    public void selectModule(HttpServletRequest request, ServletContext context) {
        // Compute module name
        String prefix = getModuleName(request, context);

        // Expose the resources for this module
        this.selectModule(prefix, request, context);
    }

getModuleName

根據請求路徑,找到匹配的prefix。

   public String getModuleName(HttpServletRequest request,
        ServletContext context) {
        // Acquire the path used to compute the module
        String matchPath =
            (String) request.getAttribute(RequestProcessor.INCLUDE_SERVLET_PATH);

        if (matchPath == null) {
            matchPath = request.getServletPath();
        }
//從這可以看出來,prefix的配置實際上是為了實現多個模組。此處就是返回相應的模組名
        return this.getModuleName(matchPath, context);
    }
再看this.selectModule(prefix,request,context)

public void selectModule(String prefix, HttpServletRequest request,
        ServletContext context) {
        // Expose the resources for this module
    	//根據prefix,和ServletContext,獲取ModuleConfig
    	//就是前面init方法中設定的玩意
        ModuleConfig config = getModuleConfig(prefix, context);
        //存在對應moduleConfig的情況
        if (config != null) {
        	//設定當前匹配的config到request中
            request.setAttribute(Globals.MODULE_KEY, config);
            //先得到messageResource配置
            MessageResourcesConfig[] mrConfig =
                config.findMessageResourcesConfigs();
            
            for (int i = 0; i < mrConfig.length; i++) {
                String key = mrConfig[i].getKey();
                //遍歷MessageResourcesConfig,找到匹配的MessageResources,然後將MessageResources放到request中
                
                MessageResources resources =
                    (MessageResources) context.getAttribute(key + prefix);
              //這裡可以看到,在配置MessageResources時,key值是要唯一的,否則可能被覆蓋掉
                if (resources != null) {
                    request.setAttribute(key, resources);
                } else {
                	
                    request.removeAttribute(key);
                }
            }
        } else {
            request.removeAttribute(Globals.MODULE_KEY);
        }
    }

實際上第一行程式碼是設定了模組的ModuleConfig到request中

2、process第二行程式碼

ModuleConfig config = getModuleConfig(request); 

回到process中,發現getModuleConfig就是從request或者ServletContext中獲取到moduleConfig

protected ModuleConfig getModuleConfig(HttpServletRequest request) {
        ModuleConfig config =
            (ModuleConfig) request.getAttribute(Globals.MODULE_KEY);

        if (config == null) {
            config =
                (ModuleConfig) getServletContext().getAttribute(Globals.MODULE_KEY);
        }

        return (config);
    }
3、process第三、四行程式碼
RequestProcessor processor = getProcessorForModule(config);
 if (processor == null) {
            processor = getRequestProcessor(config);
        }
getProcessorForModule

 private RequestProcessor getProcessorForModule(ModuleConfig config) {
        String key = Globals.REQUEST_PROCESSOR_KEY + config.getPrefix();

        return (RequestProcessor) getServletContext().getAttribute(key);
    }
在只配置一個模組的情況下,config.getPrefix()是空串。
 public static final String REQUEST_PROCESSOR_KEY =
        "org.apache.struts.action.REQUEST_PROCESSOR";

當getProcessorForModule返回null時,執行getRequestProcessor

    protected synchronized RequestProcessor getRequestProcessor(
        ModuleConfig config) throws ServletException {
        RequestProcessor processor = this.getProcessorForModule(config);

        if (processor == null) {
            try {
            	//在這裡,模組會拿到config的ControllerCOnfig
            	//如果使用者沒有配置controller,那麼config.getControllerConfig()會生成一個new ControllerConfig()
            	//而這個controller的預設ProcessorClass是org.apache.struts.chain.ComposableRequestProcessor
            	//也就是說,預設情況下,processor是org.apache.struts.chain.ComposableRequestProcessor的一個例項
                processor =
                    (RequestProcessor) RequestUtils.applicationInstance(config.getControllerConfig()
                                                                              .getProcessorClass());
            } catch (Exception e) {
                throw new UnavailableException(
                    "Cannot initialize RequestProcessor of class "
                    + config.getControllerConfig().getProcessorClass() + ": "
                    + e);
            }
            //初始化
            processor.init(this, config);

            String key = Globals.REQUEST_PROCESSOR_KEY + config.getPrefix();

            getServletContext().setAttribute(key, processor);
        }

        return (processor);
    }

4、最後一句程式碼

processor.process(request, response);
處理請求與響應