亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

struts1之ActionServlet詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

 更新時(shí)間:2017年09月04日 10:54:47   作者:lfsf802  
這篇文章主要介紹了struts1之ActionServlet詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

在web.xml中我們除了配置ActionServlet還配置了一些初始化參數(shù)信息,首先我們看第一個(gè)config參數(shù),這里配置的是/WEB-INF/struts-config.xml,因?yàn)橐旅鎮(zhèn)鬟f一個(gè)這樣一個(gè)配置信息,這個(gè)xml文件名是struts1標(biāo)準(zhǔn)的名字,所以這里這個(gè)初始化信息完全可以刪除,如果不用這個(gè)標(biāo)準(zhǔn)名稱這里就必須要在這里配置?,F(xiàn)在我們配置的是標(biāo)準(zhǔn)名字,所以我們可以刪除,這是為什么呢?這里要看ActionServlet源代碼才可以。

從圖片上我們能看到ActionServlet中已經(jīng)寫好了默認(rèn)的config信息了,就是標(biāo)準(zhǔn)名字。所以這里刪除也是可以的。
在看下面的debug和detail參數(shù),這兩個(gè)參數(shù)信息是有關(guān)日志信息級(jí)別的設(shè)置,主要關(guān)于解析配置文件/WEB-INF/struts-config.xml級(jí)別的初始化參數(shù)。這里這兩個(gè)參數(shù)可以完全去掉也不影響。

最后還有一個(gè)load-on-startup配置,這個(gè)是初始化servlet級(jí)別的初始化信息,這個(gè)參數(shù)如果大于等于0就是說(shuō)明在服務(wù)器一啟動(dòng)就把servlet初始化,也就是調(diào)用ActionServlet的init方法,這個(gè)也可以到ActionServlet的源代碼中去查找。

當(dāng)ActionServlet初始化的時(shí)候就會(huì)讀取/WEB-INF/struts-config.xml信息到內(nèi)存中,讀到內(nèi)存是以什么樣的形式展現(xiàn)的呢?我們現(xiàn)在可以看一下以前博客的那個(gè)mvc實(shí)例,那里面讀取配置文件中的信息是以Actionmapping的形式展現(xiàn)的。另外servlet-mapping的配置就不講解了,這個(gè)都知道就是匹配url路徑的,當(dāng)遇到url-pattern的路徑時(shí)候就會(huì)實(shí)例化Actionservlet。

通過(guò)這篇文章我們知道了當(dāng)我們請(qǐng)求的時(shí)候ActionServlet是怎樣實(shí)例化的,也知道為什么我們要配置web.xml信息了。那么我們?yōu)槭裁匆渲?WEB-INF/struts-config.xml文件,ActionServlet是如何傳遞請(qǐng)求的,如何和ActionForm、ActionMapping、Action等交互的最終完成用戶請(qǐng)求的呢?

我們先從ActionServlet源代碼的init方法開始。因?yàn)锳ctionServlet就是一個(gè)Servlet,它也是具有典型的那幾個(gè)方法init、doget、dopost等方法。既然是初始化,那么我們就要看init方法。Init方法的源代碼如下:

/** 
   * <p>Initialize this servlet. Most of the processing has been factored into 
   * support methods so that you can overrideparticular functionality at a 
   * fairly granular level.</p> 
   * 
   * @exception ServletException if we cannotconfigure ourselves correctly 
   */ 
  publicvoidinit() throwsServletException { 
  
    // Wraps the entire initialization in a try/catch tobetter handle 
    // unexpected exceptions and errors to provide better feedback 
    // to the developer 
    try { 
      initInternal(); 
      initOther(); 
      initServlet(); 
   
      getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this); 
      initModuleConfigFactory(); 
      // Initialize modules as needed 
      ModuleConfig moduleConfig =initModuleConfig("", config); 
      initModuleMessageResources(moduleConfig); 
      initModuleDataSources(moduleConfig); 
      initModulePlugIns(moduleConfig); 
      moduleConfig.freeze(); 
   
      Enumeration names =getServletConfig().getInitParameterNames(); 
      while (names.hasMoreElements()) { 
        String name = (String)namesnextElement(); 
        if (!name.startsWith("config/")) { 
          continue; 
        } 
        String prefix =name.substring(6); 
        moduleConfig = initModuleConfig 
          (prefix,getServletConfig().getInitParameter(name)); 
        initModuleMessageResources(moduleConfig); 
        initModuleDataSources(moduleConfig); 
        initModulePlugIns(moduleConfig); 
        moduleConfig.freeze(); 
      } 
   
      this.initModulePrefixes(this.getServletContext()); 
   
      thisdestroyConfigDigester(); 
    } catch (UnavailableException ex) { 
      throw ex; 
    } catch (Throwable t) { 
  
      // The follow error message is not retrieved from internal message 
      // resources as they may not have been able to have been 
      // initialized 
      logerror("Unable to initialize Struts ActionServlet due to an " 
        + "unexpected exception or error thrown, so marking the " 
        + "servlet as unavailable. Mostlikely, this is due to an " 
        + "incorrect or missing library dependency.", t); 
      throw new UnavailableException(t.getMessage()); 
    }   
} 

在解釋這段代碼的流程和意思之前,有必要說(shuō)一句,就是當(dāng)我們?cè)趀clipse里面看代碼的時(shí)候,尤其是看一段生疏的很長(zhǎng)的代碼的時(shí)候,希望能夠經(jīng)常使用Ctrl鍵(多余的不解釋)。

下面開始講解這段代碼的流程和具體每一步的含義,如果有不正確的地方,希望指正。

首先映入眼簾的是initInternal()方法。這個(gè)方法的實(shí)現(xiàn)代碼是:

代碼段一:

/** 
   * <p>Initialize our internal MessageResourcesbundle</p> 
   * 
   * @exception ServletException if we cannotinitialize these resources 
   */ 
  protectedvoidinitInternal() throwsServletException { 
  
    // :FIXME: Document UnavailableException 
  
    try { 
      internal = MessageResourcesgetMessageResources(internalName); 
    } catch (MissingResourceException e) { 
      log.error("Cannot load internal resources from '"+ internalName+ "'", 
        e); 
      throw new UnavailableException 
        ("Cannot load internal resources from '"+ internalName+ "'"); 
    } 
  
} 

代碼段二:

/** 
   * Create and return an instance of <code>MessageResources</code> for the 
   * created by the default <code>MessageResourcesFactory</code>. 
   * 
   * @param config Configuration parameterfor this message bundle. 
   */ 
  publicsynchronizedstaticMessageResources getMessageResources(String config) { 
  
    if (defaultFactory == null) { 
      defaultFactory =MessageResourcesFactory.createFactory(); 
    } 
  
    return defaultFactory.createResources(config); 
} 

代碼段三:

/** 
   * Create and return a <code>MessageResourcesFactory</code> instance ofthe 
   * appropriate class, which can be used tocreate customized 
   * <code>MessageResources</code>instances If no such factory can be 
   * created, return <code>null</code> instead 
   */ 
  publicstaticMessageResourcesFactory createFactory(){ 
  
    // Construct a new instance of the specified factory class 
    try { 
      if (clazz == null) 
        clazz = RequestUtils.applicationClass(factoryClass); 
      MessageResourcesFactory factory = 
        (MessageResourcesFactory) clazz.newInstance(); 
      return (factory); 
    } catch (Throwable t) { 
      LOG.error("MessageResourcesFactory.createFactory",t); 
      return (null); 
    } 
  
} 

這個(gè)方法的具體作用就是初始化MessageResources,具體實(shí)現(xiàn)是工廠模式,首先判斷defaultFactory是否存在,不存在則創(chuàng)建工廠,defaultFactory = MessageResourcesFactory.createFactory(),在通過(guò)工廠創(chuàng)建資源類defaultFactory.createResources(config);存在則直接創(chuàng)建資源類。

initOther()的方法,主要是初始化其它的配置,獲取我們自己的struts-config配置文件的路徑,而它的默認(rèn)路徑就是web-inf/struts-config.xml,另外這個(gè)方法還會(huì)注冊(cè)一些轉(zhuǎn)換類的。具體源代碼是:

/** 
   * <p>Initialize other global characteristics ofthe controller servlet</p> 
   * 
   * @exception ServletException if we cannotinitialize these resources 
   */ 
  protectedvoidinitOther() throwsServletException { 
  
    String value = null; 
    value =getServletConfig().getInitParameter("config"); 
    if (value != null) { 
      config = value; 
    } 
  
    // Backwards compatibility for form beans of Java wrapper classes 
    // Set to true for strict Struts 0 compatibility 
    value =getServletConfig().getInitParameter("convertNull"); 
    if ("true".equalsIgnoreCase(value) 
      || "yes".equalsIgnoreCase(value) 
      || "on".equalsIgnoreCase(value) 
      || "y".equalsIgnoreCase(value) 
      || "1".equalsIgnoreCase(value)) { 
  
      convertNull = true; 
    } 
  
    if (convertNull) { 
      ConvertUtils.deregister(); 
      ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class); 
      ConvertUtils.register(new BigIntegerConverter(null), BigInteger.class); 
      ConvertUtils.register(new BooleanConverter(null), Boolean.class); 
      ConvertUtils.register(new ByteConverter(null), Byte.class); 
      ConvertUtils.register(new CharacterConverter(null), Character.class); 
      ConvertUtils.register(new DoubleConverter(null), Double.class); 
      ConvertUtils.register(new FloatConverter(null), Float.class); 
      ConvertUtils.register(new IntegerConverter(null), Integer.class); 
      ConvertUtils.register(new LongConverter(null), Long.class); 
      ConvertUtils.register(new ShortConverter(null), Short.class); 
    } 
  
} 

initServlet()方法是利用digester讀取web.xml文件并且放到servletContext中。具體實(shí)現(xiàn)源代碼:

/** 
 * <p>Initialize the servlet mapping under which our controller servlet 
 * is being accessed. This will be used in the <code>&html:form></code> 
 * tag to generate correct destination URLs for form submissions.</p> 
 * 
 * @throws ServletException if error happens while scanning web.xml 
 */ 
protected void initServlet() throws ServletException { 
 
  // Remember our servlet name 
  this.servletName = getServletConfig().getServletName(); 
 
  // Prepare a Digester to scan the web application deployment descriptor 
  Digester digester = new Digester(); 
  digester.push(this); 
  digester.setNamespaceAware(true); 
  digester.setValidating(false); 
 
  // Register our local copy of the DTDs that we can find 
  for (int i = 0; i < registrations.length; i += 2) { 
    URL url = this.getClass().getResource(registrations[i+1]); 
    if (url != null) { 
      digester.register(registrations[i], url.toString()); 
    } 
  } 
 
  // Configure the processing rules that we need 
  digester.addCallMethod("web-app/servlet-mapping", 
              "addServletMapping", 2); 
  digester.addCallParam("web-app/servlet-mapping/servlet-name", 0); 
  digester.addCallParam("web-app/servlet-mapping/url-pattern", 1); 
 
  // Process the web application deployment descriptor 
  if (log.isDebugEnabled()) { 
    log.debug("Scanning web.xml for controller servlet mapping"); 
  } 
 
  InputStream input = 
    getServletContext().getResourceAsStream("/WEB-INF/web.xml"); 
 
  if (input == null) { 
    log.error(internal.getMessage("configWebXml")); 
    throw new ServletException(internal.getMessage("configWebXml")); 
  } 
 
  try { 
    digester.parse(input); 
 
  } catch (IOException e) { 
    log.error(internal.getMessage("configWebXml"), e); 
    throw new ServletException(e); 
 
  } catch (SAXException e) { 
    log.error(internal.getMessage("configWebXml"), e); 
    throw new ServletException(e); 
 
  } finally { 
    try { 
      input.close(); 
    } catch (IOException e) { 
      log.error(internal.getMessage("configWebXml"), e); 
      throw new ServletException(e); 
    } 
  } 
 
  // Record a servlet context attribute (if appropriate) 
  if (log.isDebugEnabled()) { 
    logdebug("Mapping for servlet '" + servletName + "' = '" + 
      servletMapping + "'"); 
  } 
 
  if (servletMapping != null) { 
    getServletContext().setAttribute(Globals.SERVLET_KEY, servletMapping); 
  } 
 
} 

首先說(shuō)在說(shuō)之前還是先講init方法的具體實(shí)現(xiàn)代碼寫出來(lái)以便大家方便閱讀和理解。

Init源代碼:

public void init() throws ServletException { 
  
 try { 
    //初始化資源類 
   initInternal(); 
   //注冊(cè)轉(zhuǎn)換類 
   initOther(); 
   //利用digester讀取webxml文件并且將其放到servletContext中 
   initServlet(); 
   getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this); 
    
   initModuleConfigFactory(); 
   ModuleConfig moduleConfig = initModuleConfig("", config); 
   initModuleMessageResources(moduleConfig); 
   initModuleDataSources(moduleConfig); 
   initModulePlugIns(moduleConfig); 
   moduleConfig.freeze(); 
 
   Enumeration names = getServletConfig().getInitParameterNames(); 
   while (names.hasMoreElements()) { 
     String name = (String) names.nextElement(); 
     if (!name.startsWith("config/")) { 
       continue; 
     } 
     String prefix = name.substring(6); 
     moduleConfig = initModuleConfig 
       (prefix, getServletConfig()getInitParameter(name)); 
     initModuleMessageResources(moduleConfig); 
     initModuleDataSources(moduleConfig); 
     initModulePlugIns(moduleConfig); 
     moduleConfig.freeze(); 
   } 
 
   this.initModulePrefixes(this.getServletContext()); 
 
   this.destroyConfigDigester(); 
 } catch (UnavailableException ex) { 
   throw ex; 
 } catch (Throwable t) { 
   log.error("Unable to initialize Struts ActionServlet due to an " 
     + "unexpected exception or error thrown, so marking the " 
     + "servlet as unavailable Most likely, this is due to an " 
     + "incorrect or missing library dependency", t); 
   throw new UnavailableException(t.getMessage()); 
 }   
} 

getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY,this);這句話是將ActionServlet實(shí)例將以Globals.ACTION_SERVLET_KEY作為key存入servletcontext中。

 這里的Globals.ACTION_SERVLET_KEY在ActionServlet已經(jīng)給出了聲明:

public static final String ACTION_SERVLET_KEY= "org.apache.struts.action.ACTION_SERVLET"; 

接下來(lái)initModuleConfigFactory()方法,這個(gè)方法主要的作用是解析在web.xml中configFactory的text值。如果configFactory有配置,則將設(shè)置ModuleConfigFactory中得factoryClass值,否則默認(rèn)得為efaultModuleConfigFactory。該方法其實(shí)宗旨是讓開發(fā)人員自己開發(fā)出ModuleConfigFactory,從而得到自己所需要的ModuleConfig類。因?yàn)槲覀兊膶?shí)例中沒有配置這個(gè)參數(shù)信息,所以我們這里的實(shí)例是要defalutModelConfigFactory了。

代碼段一:

protected voidinitModuleConfigFactory(){ 
    String configFactory =getServletConfig().getInitParameter("configFactory"); 
    if (configFactory != null) { 
      ModuleConfigFactory.setFactoryClass(configFactory); 
    } 
} 

代碼段二:

public static void setFactoryClass(String factoryClass) { 
    ModuleConfigFactory.factoryClass = factoryClass; 
    ModuleConfigFactory.clazz = null; 
  } 

代碼段三:

protected static String factoryClass = 
    "org.apache.struts.config.impl.DefaultModuleConfigFactory"; 
} 

ModuleConfig moduleConfig =initModuleConfig("", config)方法是非常重要的,initModuleConfig方法給strits-config里面的屬性初始化后放入moduleConfig對(duì)象里面去,放到moduleConfig對(duì)象里面去便于以后操作更快,因?yàn)樗俏募鳌?/p>

具體實(shí)現(xiàn)代碼:

protected ModuleConfig initModuleConfig(Stringprefix, String paths) 
    throws ServletException { 
  
    // :FIXME: Document UnavailableException? (Doesn't actually throw anything) 
  
    if (log.isDebugEnabled()) { 
      log.debug( 
        "Initializing module path '" 
          + prefix 
          + "' configuration from '" 
          + paths 
          + "'"); 
    } 
  
    // Parse the configuration for this module 
    ModuleConfigFactory factoryObject= ModuleConfigFactory.createFactory(); 
    ModuleConfig config =factoryObject.createModuleConfig(prefix); 
  
    // Configure the Digester instance we will use 
    Digester digester =initConfigDigester(); 
  
    // Process each specified resource path 
    while (paths.length() > 0) { 
      digester.push(config); 
      String path = null; 
      int comma = paths.indexOf(','); 
      if (comma >= 0) { 
        path =paths.substring(0, comma).trim(); 
        paths =paths.substring(comma + 1); 
      } else { 
        path = pathstrim(); 
        paths = ""; 
      } 
  
      if (pathlength() < 1){ 
        break; 
      } 
  
      this.parseModuleConfigFile(digester,path); 
    } 
  
    getServletContext().setAttribute( 
      Globals.MODULE_KEY +config.getPrefix(), 
      config); 
  
  
    // Force creation and registration of DynaActionFormClass instances 
    // for all dynamic form beans we wil be using 
    FormBeanConfig fbs[] =config.findFormBeanConfigs(); 
    for (int i = 0; i < fbs.length; i++) { 
      if (fbs[i].getDynamic()) { 
        fbs[i].getDynaActionFormClass(); 
      } 
    } 
  
    return config; 
} 

這里有必要解析一下這段代碼。首先得到繼承ModuleConfigFactory的實(shí)現(xiàn)類,如果在initModuleConfigFactory()中能設(shè)置factoryClass屬性,則能生成客戶化得factory,否則得到得是默認(rèn)得DefaultModuleConfigFactory類,該工廠得到ModuleConfigImpl類。然后調(diào)用initConfigDigester()該方法為解析配置文件做準(zhǔn)備,初始化Digest類(具體digest的初始化實(shí)現(xiàn)就不講解)。最后返回ModuleConfig,而這時(shí)的ModuleConfig里面封裝了所有的struts-config.xml中的信息。

最后的幾個(gè)方法就簡(jiǎn)單說(shuō)一下就行,不是非常難理解:

initModuleMessageResources(moduleConfig)方法是通過(guò)moduleConfig中的配置文件信息,創(chuàng)建MessageResource對(duì)象.

initModuleDataSources(moduleConfig)方法是通過(guò)moduleConfig中的配置文件信息,創(chuàng)建DataSource對(duì)象.   initModulePlugIns(moduleConfig)加載并初始化默認(rèn)應(yīng)用模塊的所有插件的。

moduleConfig.freeze()是將配置文件中的各個(gè)對(duì)象,設(shè)置成已配置狀態(tài).

最后我們看到了,下面還有一段同上面代碼的循環(huán)代碼,這段代碼的主要意思就是當(dāng)默認(rèn)子應(yīng)用模塊被成功初始化后,如果應(yīng)用還包括其他子應(yīng)用模塊,將重復(fù)流程,分別對(duì)其他子應(yīng)用模塊進(jìn)行初始化。這個(gè)也是很好理解的。

到此為止ActionServlet就init完成。

相關(guān)文章

  • java使用Jdom實(shí)現(xiàn)xml文件寫入操作實(shí)例

    java使用Jdom實(shí)現(xiàn)xml文件寫入操作實(shí)例

    這篇文章主要介紹了java使用Jdom實(shí)現(xiàn)xml文件寫入操作的方法,以完整實(shí)例形式分析了Jdom針對(duì)XML文件寫入操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-10-10
  • Spring循環(huán)依賴代碼演示及解決方案

    Spring循環(huán)依賴代碼演示及解決方案

    這篇文章主要介紹了Spring循環(huán)依賴實(shí)現(xiàn)過(guò)程,Spring的解決循環(huán)依賴是有前置條件的,要解決循環(huán)依賴我們首先要了解Spring Bean對(duì)象的創(chuàng)建過(guò)程和依賴注入的方式
    2023-04-04
  • java自定義注解接口實(shí)現(xiàn)方案

    java自定義注解接口實(shí)現(xiàn)方案

    java注解是附加在代碼中的一些元信息,用于一些工具在編譯、運(yùn)行時(shí)進(jìn)行解析和使用,起到說(shuō)明、配置的功能,本文將詳細(xì)介紹,此功能的實(shí)現(xiàn)方法
    2012-11-11
  • SpringBoot + Shiro前后端分離權(quán)限

    SpringBoot + Shiro前后端分離權(quán)限

    這篇文章主要為大家詳細(xì)介紹了SpringBoot + Shiro前后端分離權(quán)限,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • Java ThreadLocal 線程安全問(wèn)題解決方案

    Java ThreadLocal 線程安全問(wèn)題解決方案

    這篇文章主要介紹了Java ThreadLocal 線程安全問(wèn)題解決方案的相關(guān)資料,需要的朋友可以參考下
    2016-09-09
  • MyBatis-Plus實(shí)現(xiàn)多數(shù)據(jù)源的示例代碼

    MyBatis-Plus實(shí)現(xiàn)多數(shù)據(jù)源的示例代碼

    這篇文章主要介紹了MyBatis-Plus實(shí)現(xiàn)多數(shù)據(jù)源的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 教你在JNA中將本地方法映射到JAVA代碼中的示例

    教你在JNA中將本地方法映射到JAVA代碼中的示例

    對(duì)于JNI來(lái)說(shuō),我們可以使用native關(guān)鍵字來(lái)定義本地方法。那么在JNA中有那些在JAVA代碼中定義本地方法的方式呢?對(duì)JNA本地方法映射JAVA代碼的相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-04-04
  • Hibernate雙向一對(duì)一映射關(guān)系配置代碼實(shí)例

    Hibernate雙向一對(duì)一映射關(guān)系配置代碼實(shí)例

    這篇文章主要介紹了Hibernate雙向一對(duì)一映射關(guān)系配置代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 十大常見Java String問(wèn)題_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    十大常見Java String問(wèn)題_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    本文介紹Java中關(guān)于String最常見的10個(gè)問(wèn)題,需要的朋友參考下吧
    2017-04-04
  • 徹底理解Java中的ThreadLocal

    徹底理解Java中的ThreadLocal

     ThreadLocal翻譯成中文比較準(zhǔn)確的叫法應(yīng)該是:線程局部變量。使用這個(gè)工具類可以很簡(jiǎn)潔地編寫出優(yōu)美的多線程程序。 接下來(lái)通過(guò)本文給大家介紹Java中的ThreadLocal,需要的朋友可以參考下
    2017-03-03

最新評(píng)論