struts1原始碼學習6(doPost和doGet)
阿新 • • 發佈:2018-11-29
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。
再看this.selectModule(prefix,request,context)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); }
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);
處理請求與響應