struts1.3执行流程分析
生活随笔
收集整理的這篇文章主要介紹了
struts1.3执行流程分析
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
這是在去年9月份,讀了一下struts1.3的源碼,記錄了一下執(zhí)行流程。發(fā)出來(lái)和大家分享一下吧。這個(gè)流程還是很經(jīng)典的吧。有空再讀讀struts2的^_^
執(zhí)行流程:
1、ActionServlet處理.do的請(qǐng)求 不管是get還是post方式都將轉(zhuǎn)到?? ?protected void process(HttpServletRequest request, HttpServletResponse response) 方法。
?? ?
2、根據(jù)請(qǐng)求對(duì)象和servletContext對(duì)象選擇請(qǐng)求所隸屬的模塊
?? ?ModuleUtils.getInstance().selectModule(request, getServletContext());
?? ?
3、加載模塊配置對(duì)象 ModuleConfig config = getModuleConfig(request);
4、加載請(qǐng)求處理對(duì)象
?? ?RequestProcessor processor = getProcessorForModule(config);
??????? if (processor == null) {
??????????? processor = getRequestProcessor(config);
??????? }
?? ??? ?
5、調(diào)用請(qǐng)求對(duì)象(processor)對(duì)象的
?? ?public void process(HttpServletRequest request, HttpServletResponse response)
?? ??? ?throws IOException, ServletException
?? ?方法處理請(qǐng)求。
?? ?
6、對(duì)mutipart請(qǐng)求(上傳)進(jìn)行特殊包裝 request = processMultipart(request);
?? ?1、首先判斷是否為post方式,如果不是post方式,則肯定不是上傳請(qǐng)求,則直接返回request對(duì)象
?? ??? ?if (!"POST".equalsIgnoreCase(request.getMethod())) {
??????????? return (request);
??????? }
?? ??? ?
?? ?2、獲取request對(duì)象的ContentType,如果ContentType為multipart/form-datade 話則 new 一個(gè) MultipartRequestWrapper 對(duì)象返回。否則直接返回request。
?? ??? ?String contentType = request.getContentType();
??????? if ((contentType != null)
??????????? && contentType.startsWith("multipart/form-data")) {
??????????? return (new MultipartRequestWrapper(request));
??????? } else {
??????????? return (request);
??????? }
?? ??? ?
?? ??? ?1、MultipartRequestWrapper繼承于HttpServletRequestWrapper。下面是包裝代碼
?? ??? ??? ?public MultipartRequestWrapper(HttpServletRequest request) {
?? ??? ??? ??? ?super(request);
?? ??? ??? ??? ?this.parameters = new HashMap();
?? ??? ??? ?}
?? ??? ??? ?
7、處理請(qǐng)求路徑
?? ?String path = processPath(request, response); 返回的是訪問(wèn)的action的名字
?? ?
8、如果返回值是空, 則方法直接return,結(jié)束。
?? ?if (path == null) {
?? ??? ?return;
?? ?}
?? ?
9、把請(qǐng)求的方式(post/get)和action名字記入日志
?? ?if (log.isDebugEnabled()) {
?? ??? ?log.debug("Processing a '" + request.getMethod() + "' for path '"
?? ??? ??? ?+ path + "'");
?? ?}
?? ?
10、為當(dāng)前的用戶請(qǐng)求選擇對(duì)應(yīng)的local(區(qū)域和語(yǔ)言),這是根據(jù)瀏覽器的設(shè)置的。涉及到國(guó)際化問(wèn)題。
?? ?// Select a Locale for the current user if requested
??? processLocale(request, response);
11、為response對(duì)象設(shè)置ContentType和no-cache的header信息。
?? ?// Set the content type and no-caching headers if requested
?? ?processContent(request, response);
?? ?processNoCache(request, response);
12、留了一個(gè)可以預(yù)處理請(qǐng)求的擴(kuò)展接口。
?? ?// General purpose preprocessing hook
?? ?if (!processPreprocess(request, response)) {
?? ??? ?return;
?? ?}?? ?? 這里processPreprocess方法只有一句話:return(true);其實(shí)是為了可以擴(kuò)展,如果要對(duì)請(qǐng)求預(yù)處理,可以繼承這個(gè)類,然后重寫這個(gè)
?? ?protected boolean processPreprocess(HttpServletRequest request,HttpServletResponse response) {
??????? return (true);
??? }
方法。
13、處理以前緩存的信息
?? ?this.processCachedMessages(request, response);
?? ?其實(shí)就是清空session里如果存在的struts定義的提示信息和錯(cuò)誤信息。?? ?
14、根據(jù)request,response,和path(action的名字)返回actionMapping對(duì)象。
?? ?// Identify the mapping for this request
?? ?ActionMapping mapping = processMapping(request, response, path);
?? ?if (mapping == null) {
?? ??? ?return;
?? ?}
?? ?
?? ?1、首先去配置文件里找相應(yīng)的配置信息
?? ??? ?// Is there a mapping for this path?
??????? ActionMapping mapping = (ActionMapping) moduleConfig.findActionConfig(path);
?? ?
?? ?2、如果有配置則把它放入request,并返回他。
?? ??? ?// If a mapping is found, put it in the request and return it
??????? if (mapping != null) {
??????????? request.setAttribute(Globals.MAPPING_KEY, mapping);
??????????? return (mapping);
??????? }
?? ??? ?
?? ?3、找到“未知的映射路徑(如果有的話)”。同樣找到了就放到request里并返回他。
?? ??? ?// 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);
??????????? }
??????? }
?? ?
?? ?4、如果還是沒(méi)有找到mapping信息則發(fā)送錯(cuò)誤消息,并返回null
?? ??? ?// 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;
15、檢查執(zhí)行這個(gè)action所要的所有角色(是否有權(quán)訪問(wèn))
?? ?// Check for any role required to perform this action
?? ?if (!processRoles(request, response, mapping)) {
?? ??? ?return;
?? ?}
?? ?
?? ?1、從actionMapping(mapping)對(duì)想里取得角色名稱的數(shù)組。
?? ??? ?// Is this action protected by role requirements?
??????? String[] roles = mapping.getRoleNames();
?? ??? ?
?? ?2、如果mapping里沒(méi)有角色信息(沒(méi)有配置),就不做處理,直接返回true
?? ??? ?if ((roles == null) || (roles.length < 1)) {
??????????? return (true);
??????? }
?? ??? ?
?? ?3、依次取出配置了的角色 ,如果用戶在角色中 (配置了的所有角色中的任意一個(gè)) ,則把用戶名和角色名記 錄到log里。并返回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);
??????????? }
??????? }
?? ??? ?
?? ?4、如果仍沒(méi)找到用戶所對(duì)應(yīng)的角色,則說(shuō)明這個(gè)用戶是非法訪問(wèn)的。則把這個(gè)用戶名記錄到log里,發(fā)送錯(cuò)誤信息,并返回false。
?? ??? ?// 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);
16、處理與這個(gè)請(qǐng)求有關(guān)的所有actionForm。(調(diào)用processActionForm()方法返回ActionForm對(duì)象)
?? ?// Process any ActionForm bean related to this request
??? ActionForm form = processActionForm(request, response, mapping);
?? ?
?? ?1、如果有需要就新建一個(gè)ActionForm來(lái)供使用。
?? ??? ?// Create (if necessary) a form bean to use
??????? ActionForm instance = RequestUtils.createActionForm(request, mapping, moduleConfig, servlet);
?? ??? ?
?? ??? ?1、查看mapping里是否配置name屬性或attribute屬性來(lái)指定ActionForm,如果都沒(méi)有則返回null
?? ??? ??? ?// Is there a form bean associated with this mapping?
?? ??? ??? ?String attribute = mapping.getAttribute();
?? ??? ??? ?if (attribute == null) {
?? ??? ??? ??? ?return (null);
?? ??? ??? ?}
?? ??? ?
?? ??? ?2、通過(guò)name屬性拿到ActionForm的配置信息
?? ??? ??? ?// Look up the form bean configuration information to use
?? ??? ??? ?String name = mapping.getName();
?? ??? ??? ?FormBeanConfig config = moduleConfig.findFormBeanConfig(name);
?? ??? ?
?? ??? ?3、如果沒(méi)有與name屬性相對(duì)應(yīng)的<form-bean>配置,則在log里記錄:沒(méi)有配置與name對(duì)應(yīng)的formBean,并返回null;
?? ??? ??? ?if (config == null) {
?? ??? ??? ??? ?log.warn("No FormBeanConfig found under '" + name + "'");
?? ??? ??? ??? ?return (null);
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ?4、根據(jù)拿到的<form-bean>配置,在相應(yīng)的范圍里(request,session)找ActionForm的實(shí)例
?? ??? ??? ?ActionForm instance = lookupActionForm(request, attribute, mapping.getScope());
?? ??? ?
?? ??? ?5、如果找到,并被判定為可用,則返回找到的實(shí)例。
?? ??? ??? ?// Can we recycle the existing form bean instance (if there is one)?
?? ??? ??? ?if ((instance != null) && config.canReuse(instance)) {
?? ??? ??? ??? ?return (instance);
?? ??? ??? ?}
?? ??? ?
?? ??? ?6、如果沒(méi)找到,(前面已經(jīng)確定配置了formBean)。則新建一個(gè)ActionForm對(duì)象出來(lái)并返回他。
?? ??? ??? ?return createActionForm(config, servlet);
?? ??? ??? ?
?? ??? ??? ?1、首先判斷傳入的config,如果config為null,則直接返回null
?? ??? ??? ??? ?if (config == null) {
?? ??? ??? ??? ??? ?return (null);
?? ??? ??? ??? ?}
?? ??? ??? ?
?? ??? ??? ?2、創(chuàng)建并返回一個(gè)新的ActionForm對(duì)象。這里調(diào)用了config對(duì)象的createActionForm方法。該方法里肯定用到了反射機(jī)制。另外把創(chuàng)建的ActionForm或動(dòng)態(tài)ActionForm的信息存到log里。同樣,如果過(guò)程中出錯(cuò),錯(cuò)誤信息業(yè)將被保存到日志里。
?? ??? ??? ??? ?ActionForm instance = null;
?? ??? ??? ??? ?// Create and return a new form bean instance
?? ??? ??? ??? ?try {
?? ??? ??? ??? ??? ?instance = config.createActionForm(servlet);
?? ??? ??? ??? ??? ?if (log.isDebugEnabled()) {
?? ??? ??? ??? ??? ??? ?log.debug(" Creating new "
?? ??? ??? ??? ??? ??? ??? ?+ (config.getDynamic() ? "DynaActionForm" : "ActionForm")
?? ??? ??? ??? ??? ??? ??? ?+ " instance of type '" + config.getType() + "'");
?? ??? ??? ??? ??? ??? ?log.trace(" --> " + instance);
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?} catch (Throwable t) {
?? ??? ??? ??? ??? ?log.error(servlet.getInternal().getMessage("formBean",
?? ??? ??? ??? ??? ??? ??? ?config.getType()), t);
?? ??? ??? ??? ?}
?? ??? ??? ??? ?return (instance);
?? ??? ??? ??? ?
17、為ActionForm填充數(shù)據(jù)。
?? ?processPopulate(request, response, form, mapping);
?? ?
?? ?1、首先判斷form是否為null,如果是則直接return。
?? ??? ?if (form == null) {
??????????? return;
??????? }
?? ?
?? ?2、往log里寫入一句話提示從這里開始填充formBean
?? ??? ?if (log.isDebugEnabled()) {
??????????? log.debug(" Populating bean properties from this request");
??????? }
?? ?
?? ?3、設(shè)置Servlet。
?? ??? ?form.setServlet(this.servlet);
?? ??? ?(不知道具體作用)
?? ??? ?
?? ?4、執(zhí)行reset方法重置表單。默認(rèn)reset方法不做任何事情。這個(gè)方法是為了方便擴(kuò)展。可以繼承ActionForm類重寫reset方法,這個(gè)方法可以用來(lái)做設(shè)置一些默認(rèn)值等工作。
?? ??? ?form.reset(mapping, request);
?? ??? ?
?? ?5、如果是上傳表單,則獲取上傳類。(不甚了解)
?? ??? ?if (mapping.getMultipartClass() != null) {
??????????? request.setAttribute(Globals.MULTIPART_KEY,
??????????????? mapping.getMultipartClass());
??????? }
?? ?
?? ?6、填充form
?? ??? ?RequestUtils.populate(form, mapping.getPrefix(), mapping.getSuffix(), request);
?? ??? ?
?? ??? ?1、建立一個(gè)HashMap 用于存放屬性
?? ??? ??? ?// Build a list of relevant request parameters from this request
?? ??? ??? ?HashMap properties = new HashMap();
?? ??? ??? ?
?? ??? ?2、建立一個(gè)Enumeration用于存放參數(shù)名
?? ??? ??? ?// Iterator of parameter names
?? ??? ??? ?Enumeration names = null;
?? ??? ?
?? ??? ?3、建立一個(gè)Map來(lái)存放multipart參數(shù)
?? ??? ??? ?// Map for multipart parameters
?? ??? ??? ?Map multipartParameters = null;
?? ??? ?
?? ??? ?4、獲取請(qǐng)求的ContentType和Method。并設(shè)置multipart表示為false。
?? ??? ??? ?String contentType = request.getContentType();
?? ??? ??? ?String method = request.getMethod();
?? ??? ??? ?boolean isMultipart = false;
?? ??? ??? ?
?? ??? ?5、如果是multipart表單則做上傳處理(不甚了解)
?? ??? ??? ?if (bean instanceof ActionForm) {
?? ??? ??? ??? ?((ActionForm) bean).setMultipartRequestHandler(null);
?? ??? ??? ?}
?? ??? ??? ?MultipartRequestHandler multipartHandler = null;
?? ??? ??? ?if ((contentType != null)
?? ??? ??? ??? ?&& (contentType.startsWith("multipart/form-data"))
?? ??? ??? ??? ?&& (method.equalsIgnoreCase("POST"))) {
?? ??? ??? ??? ?// Get the ActionServletWrapper from the form bean
?? ??? ??? ??? ?ActionServletWrapper servlet;
?? ??? ??? ??? ?if (bean instanceof ActionForm) {
?? ??? ??? ??? ??? ?servlet = ((ActionForm) bean).getServletWrapper();
?? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ?throw new ServletException("bean that's supposed to be "
?? ??? ??? ??? ??? ??? ?+ "populated from a multipart request is not of type "
?? ??? ??? ??? ??? ??? ?+ "\"org.apache.struts.action.ActionForm\", but type "
?? ??? ??? ??? ??? ??? ?+ "\"" + bean.getClass().getName() + "\"");
?? ??? ??? ??? ?}
?? ??? ??? ??? ?// Obtain a MultipartRequestHandler
?? ??? ??? ??? ?multipartHandler = getMultipartHandler(request);
?? ??? ??? ??? ?if (multipartHandler != null) {
?? ??? ??? ??? ??? ?isMultipart = true;
?? ??? ??? ??? ??? ?// Set servlet and mapping info
?? ??? ??? ??? ??? ?servlet.setServletFor(multipartHandler);
?? ??? ??? ??? ??? ?multipartHandler.setMapping((ActionMapping) request
?? ??? ??? ??? ??? ??? ?.getAttribute(Globals.MAPPING_KEY));
?? ??? ??? ??? ??? ?// Initialize multipart request class handler
?? ??? ??? ??? ??? ?multipartHandler.handleRequest(request);
?? ??? ??? ??? ??? ?//stop here if the maximum length has been exceeded
?? ??? ??? ??? ??? ?Boolean maxLengthExceeded =
?? ??? ??? ??? ??? ??? ?(Boolean) request.getAttribute(MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED);
?? ??? ??? ??? ??? ?if ((maxLengthExceeded != null)
?? ??? ??? ??? ??? ??? ?&& (maxLengthExceeded.booleanValue())) {
?? ??? ??? ??? ??? ??? ?((ActionForm) bean).setMultipartRequestHandler(multipartHandler);
?? ??? ??? ??? ??? ??? ?return;
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?//retrieve form values and put into properties
?? ??? ??? ??? ??? ?multipartParameters =
?? ??? ??? ??? ??? ??? ?getAllParametersForMultipartRequest(request,
?? ??? ??? ??? ??? ??? ??? ?multipartHandler);
?? ??? ??? ??? ??? ?names = Collections.enumeration(multipartParameters.keySet());
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ?6、如果不是上傳,則把參數(shù)名存到names枚舉里面。
?? ??? ??? ?if (!isMultipart) {
?? ??? ??? ??? ?names = request.getParameterNames();
?? ??? ??? ?}
?? ??? ?
?? ??? ?7、遍歷這個(gè)枚舉
?? ??? ??? ?while (names.hasMoreElements())
?? ??? ??? ?
?? ??? ??? ?1、把名字拿出來(lái)存到name和stripped變量里
?? ??? ??? ??? ?String name = (String) names.nextElement();
?? ??? ??? ??? ?String stripped = name;
?? ??? ??? ??? ?
?? ??? ??? ?2、去掉name的前綴和后綴(如果有的話(配置文件里可以配置))
?? ??? ??? ??? ?if (prefix != null) {
?? ??? ??? ??? ??? ?if (!stripped.startsWith(prefix)) {
?? ??? ??? ??? ??? ??? ?continue;
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?stripped = stripped.substring(prefix.length());
?? ??? ??? ??? ?}
?? ??? ??? ??? ?if (suffix != null) {
?? ??? ??? ??? ??? ?if (!stripped.endsWith(suffix)) {
?? ??? ??? ??? ??? ??? ?continue;
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?stripped =
?? ??? ??? ??? ??? ??? ?stripped.substring(0, stripped.length() - suffix.length());
?? ??? ??? ??? ?}
?? ??? ??? ??? ?
?? ??? ??? ?3、獲取參數(shù)值,分上傳和非上傳兩種方式
?? ??? ??? ??? ?Object parameterValue = null;
?? ??? ??? ??? ?if (isMultipart) {
?? ??? ??? ??? ??? ?parameterValue = multipartParameters.get(name);
?? ??? ??? ??? ??? ?parameterValue = rationalizeMultipleFileProperty(bean, name, parameterValue);
?? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ?parameterValue = request.getParameterValues(name);
?? ??? ??? ??? ?}
?? ??? ??? ??? ?
?? ??? ??? ?4、如果參數(shù)名去掉了前后綴后不是一org.Apache.struts開頭則把參數(shù)存到定義好的HashMap里
?? ??? ??? ??? ?// Populate parameters, except "standard" struts attributes
?? ??? ??? ??? ?// such as 'org.apache.struts.action.CANCEL'
?? ??? ??? ??? ?if (!(stripped.startsWith("org.apache.struts."))) {
?? ??? ??? ??? ??? ?properties.put(stripped, parameterValue);
?? ??? ??? ??? ?}
?? ??? ??? ??? ?
?? ??? ?8、調(diào)用BeanUtils的方法把formBean的屬性填充進(jìn)去(異常處理那塊不是很明白)
?? ??? ??? ?// Set the corresponding properties of our bean
?? ??? ??? ?try {
?? ??? ??? ??? ?BeanUtils.populate(bean, properties);
?? ??? ??? ?} catch (Exception e) {
?? ??? ??? ??? ?throw new ServletException("BeanUtils.populate", e);
?? ??? ??? ?} finally {
?? ??? ??? ??? ?if (multipartHandler != null) {
?? ??? ??? ??? ??? ?// Set the multipart request handler for our ActionForm.
?? ??? ??? ??? ??? ?// If the bean isn't an ActionForm, an exception would have been
?? ??? ??? ??? ??? ?// thrown earlier, so it's safe to assume that our bean is
?? ??? ??? ??? ??? ?// in fact an ActionForm.
?? ??? ??? ??? ??? ?((ActionForm) bean).setMultipartRequestHandler(multipartHandler);
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?
?? ?7、加入合適的話就把退出屬性設(shè)置到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);
??????? }
?? ??? ?
18、驗(yàn)證表單輸入的合法性。如果有不合法的則return。(一般不用struts的表單級(jí)驗(yàn)證)
?? ?// 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;
?? ?}
?? ?
19、處理mapping指定的forward 和 include
?? ?// Process a forward or include specified by this mapping
?? ?if (!processForward(request, response, mapping)) {
?? ??? ?return;
?? ?}
?? ?if (!processInclude(request, response, mapping)) {
?? ??? ?return;
?? ?}
?? ?
20、創(chuàng)建或者獲取一個(gè)Action的實(shí)例來(lái)處理請(qǐng)求。
?? ?// Create or acquire the Action instance to process this request
??? Action action = processActionCreate(request, response, mapping);
?? ?
?? ?1、從mapping里取出配置的Action類名
?? ??? ?// Acquire the Action instance we will be using (if there is one)
?? ??? ?String className = mapping.getType();
?? ?
?? ?2、把查找Action實(shí)例的動(dòng)作記入到日志里
?? ??? ?if (log.isDebugEnabled()) {
?? ??? ??? ?log.debug(" Looking for Action instance for class " + className);
?? ??? ?}
?? ?3、在拿到Action實(shí)例之前先線程同步synchronized (actions) ,保證只有一個(gè)Action實(shí)例
?? ?
?? ?4、從map里取出Action返回,(如果有的話),并把結(jié)果寫入日志
?? ??? ?nstance = (Action) actions.get(className);
?? ??? ?if (instance != null) {
?? ??? ??? ?if (log.isTraceEnabled()) {
?? ??? ??? ??? ?log.trace("? Returning existing Action instance");
?? ??? ??? ?}
?? ??? ??? ?return (instance);
?? ??? ?}
?? ?
?? ?5、如果上面的操作沒(méi)進(jìn)行,那說(shuō)明要新建一個(gè)Action實(shí)例,把新建實(shí)例的動(dòng)作記錄到日志里
?? ??? ?if (log.isTraceEnabled()) {
?? ??? ??? ?log.trace("? Creating new Action instance");
?? ??? ?}
?? ??? ?
?? ?6、創(chuàng)建出Action實(shí)例,吧實(shí)例放到map里并返回實(shí)例
?? ??? ?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);
?? ??? ?
21、再次判斷Action是否創(chuàng)建成功,如果沒(méi)有則方法直接return
?? ??? ?if (action == null) {
?? ??? ??? ?return;
?? ??? ?}
?? ??? ?
22、執(zhí)行Action的excute方法,獲得ActionForward
?? ??? ?// Call the Action instance itself
?? ??? ?ActionForward forward = processActionPerform(request, response, action, form, mapping);
?? ??? ?其中processActionPerform方法調(diào)用了action的excute方法:
?? ??? ?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));
?? ??? ??? ?}
?? ??? ?}
?? ?這里也做了一個(gè)處理,如果要在執(zhí)行excute方法之前做一些操作,就可以覆蓋processActionPerform方法。
?? ?
23、更具Actionforward進(jìn)行轉(zhuǎn)發(fā)
?? ??? ?// Process the returned ActionForward instance
?? ??? ?processForwardConfig(request, response, forward);
?? ?
?? ??? ?1、如果ActionForward為空,則方法直接返回
?? ??? ??? ?if (forward == null) {
?? ??? ??? ??? ?return;
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ?2、把接下來(lái)處理forward的操作記錄到日志里
?? ??? ??? ?if (log.isDebugEnabled()) {
?? ??? ??? ??? ?log.debug("processForwardConfig(" + forward + ")");
?? ??? ??? ?}
?? ??? ?
?? ??? ?3、從mapping里獲取forward對(duì)應(yīng)的url,默認(rèn)用forward的方式轉(zhuǎn)發(fā),如果配了redirect,則用redirect重定向
?? ??? ??? ?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);
?? ??? ??? ?}
在讀源碼的時(shí)候難免會(huì)出現(xiàn)一些理解上的錯(cuò)誤,如果哪位發(fā)現(xiàn)了上面寫的不對(duì),麻煩告訴我一下。
轉(zhuǎn)載于:https://www.cnblogs.com/coffee/archive/2010/03/01/1675726.html
總結(jié)
以上是生活随笔為你收集整理的struts1.3执行流程分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C# 3.0 扩展方法
- 下一篇: x86 vs x64