ホームページ Java &#&チュートリアル struts1のActionServletサンプルの詳細説明

struts1のActionServletサンプルの詳細説明

Sep 05, 2017 am 11:31 AM
詳しい説明

この記事では主に struts1 の ActionServlet の詳細な説明を紹介します。これが非常に優れていると思いますので、参考にしてください。エディターに従って見てみましょう

web.xml では、ActionServlet の構成に加えて、いくつかの初期化パラメーター情報も構成します。まず、ここで構成されているのは /WEB-INF/struts です。 -config.xml 。このような構成情報は以下に渡す必要があるため、この XML ファイルの名前は struts1 の標準名であるため、この標準名が使用されない場合は、この初期化情報を完全に削除する必要があります。ここで設定されます。ここで標準名を設定したので、削除できるようになりました。これはなぜでしょうか?ここで、ActionServlet のソース コードを確認する必要があります。

写真を見ると、標準名であるActionServletにデフォルトの設定情報が書き込まれていることが分かります。したがって、ここで削除することも可能です。
以下のデバッグパラメータと詳細パラメータを見てください。これらの 2 つのパラメータ情報は、主に構成ファイル/WEB-INF/struts-config.xml レベルでの初期化パラメータの解析に関するログ情報レベルの設定に関連しています。ここでのこれら 2 つのパラメーターは、何の影響もなく完全に削除できます。

最後に、load-on-startup 構成があります。これは、サーブレット レベルを初期化するための初期化情報です。このパラメーターが 0 以上の場合、サーバーが起動するとすぐにサーブレットが初期化されることを意味します。つまり、ActionServlet の init メソッドが呼び出されます。これは、ActionServlet のソース コードに移動して見つけることもできます。

ActionServlet が初期化されると、/WEB-INF/struts-config.xml 情報がメモリに読み込まれ、メモリはどのような形式で表示されますか?前回のブログの mvc インスタンスを見てみましょう。構成ファイルに読み取られた情報がアクションマッピングの形式で表示されます。さらに、サーブレット マッピングの構成については説明しませんが、URL パターン パスに一致すると、Actionservlet がインスタンス化されることがわかります。

この記事を通じて、ActionServlet がリクエストされたときにどのようにインスタンス化されるか、そしてなぜ web.xml 情報を設定する必要があるのか​​を理解しました。では、なぜ /WEB-INF/struts-config.xml ファイルを設定するのでしょうか? ActionServlet はどのようにリクエストを転送するのでしょうか? 最終的にユーザーのリクエストを完了するために、ActionForm、ActionMapping、Action などとどのようにやり取りするのでしょうか?

ActionServlet ソース コードの init メソッドから始めましょう。 ActionServlet はサーブレットであるため、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()); 
    }   
}
ログイン後にコピー

このコードのプロセスと意味を説明する前に、Eclipse のコードを見るとき、特に長くて見慣れない段落 コーディングの際、Ctrlキーを頻繁に使えるようになりたいです(余計な説明は無し)。

このコードのプロセスと各ステップの具体的な意味を説明していきます。間違いがある場合は修正したいと思います。

最初に目に入るのは initInternal() メソッドです。このメソッドの実装コードは次のとおりです。codeセグメント1:


rreee

codeセグメント2:


rreee

codeセグメント3:


rreeeこのメソッドの特定の機能初期化 MessageResources の場合、具体的な実装はファクトリ モードです。まず、defaultFactory が存在するかどうかを確認し、ファクトリの defaultFactory = MessageResourcesFactory.createFactory() を使用してリソース クラスを作成します。 ; 存在する場合は、リソース クラスを直接作成します。


initOther() メソッドは主に他の構成を初期化し、独自の struts-config 構成ファイルのパスを取得するために使用されます。そのデフォルトのパスは web-inf/struts-config.xml です。さらに、このメソッドはいくつかのファイルも登録します。変換タイプ。具体的なソース コードは次のとおりです。



/** 
   * <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 &#39;"+ internalName+ "&#39;", 
        e); 
      throw new UnavailableException 
        ("Cannot load internal resources from &#39;"+ internalName+ "&#39;"); 
    } 
  
}
ログイン後にコピー

initServlet() メソッドは、ダイジェスターを使用して web.xml ファイルを読み取り、それを servletContext に置きます。具体的な実装ソースコード:



/** 
   * 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); 
}
ログイン後にコピー

まず、その話をする前に、init メソッドの具体的な実装コードを、誰でも簡単に読んで理解できるように書き留めておきます。


Init ソース コード:


/** 
   * 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); 
    } 
  
}
ログイン後にコピー

getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY,this); この文は、ActionServlet インスタンスが Globals.ACTION_SERVLET_KEY をキーとしてサーブレット コンテキストに保存されることを意味します。


ここの Globals.ACTION_SERVLET_KEY は ActionServlet で宣言されています:


public static final String ACTION_SERVLET_KEY= "org.apache.struts.action.ACTION_SERVLET";
ログイン後にコピー

接下来initModuleConfigFactory()方法,这个方法主要的作用是解析在web.xml中configFactory的text值。如果configFactory有配置,则将设置ModuleConfigFactory中得factoryClass值,否则默认得为efaultModuleConfigFactory。该方法其实宗旨是让开发人员自己开发出ModuleConfigFactory,从而得到自己所需要的ModuleConfig类。因为我们的实例中没有配置这个参数信息,所以我们这里的实例是要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对象里面去,放到moduleConfig对象里面去便于以后操作更快,因为它是文件流。

具体实现代码:


protected ModuleConfig initModuleConfig(Stringprefix, String paths) 
    throws ServletException { 
  
    // :FIXME: Document UnavailableException? (Doesn&#39;t actually throw anything) 
  
    if (log.isDebugEnabled()) { 
      log.debug( 
        "Initializing module path &#39;" 
          + prefix 
          + "&#39; configuration from &#39;" 
          + paths 
          + "&#39;"); 
    } 
  
    // 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(&#39;,&#39;); 
      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的实现类,如果在initModuleConfigFactory()中能设置factoryClass属性,则能生成客户化得factory,否则得到得是默认得DefaultModuleConfigFactory类,该工厂得到ModuleConfigImpl类。然后调用initConfigDigester()该方法为解析配置文件做准备,初始化Digest类(具体digest的初始化实现就不讲解)。最后返回ModuleConfig,而这时的ModuleConfig里面封装了所有的struts-config.xml中的信息。

最后的几个方法就简单说一下就行,不是非常难理解:

initModuleMessageResources(moduleConfig)方法是通过moduleConfig中的配置文件信息,创建MessageResource对象.

initModuleDataSources(moduleConfig)方法是通过moduleConfig中的配置文件信息,创建DataSource对象.   initModulePlugIns(moduleConfig)加载并初始化默认应用模块的所有插件的。

moduleConfig.freeze()是将配置文件中的各个对象,设置成已配置状态.

最后我们看到了,下面还有一段同上面代码的循环代码,这段代码的主要意思就是当默认子应用模块被成功初始化后,如果应用还包括其他子应用模块,将重复流程,分别对其他子应用模块进行初始化。这个也是很好理解的。

到此为止ActionServlet就init完成。

以上がstruts1のActionServletサンプルの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Win11での管理者権限の取得について詳しく解説 Win11での管理者権限の取得について詳しく解説 Mar 08, 2024 pm 03:06 PM

Windows オペレーティング システムは世界で最も人気のあるオペレーティング システムの 1 つであり、その新バージョン Win11 が大きな注目を集めています。 Win11 システムでは、管理者権限の取得は重要な操作であり、管理者権限を取得すると、ユーザーはシステム上でより多くの操作や設定を実行できるようになります。この記事では、Win11システムで管理者権限を取得する方法と、権限を効果的に管理する方法を詳しく紹介します。 Win11 システムでは、管理者権限はローカル管理者とドメイン管理者の 2 種類に分かれています。ローカル管理者はローカル コンピュータに対する完全な管理権限を持っています

C++のmode関数の詳しい解説 C++のmode関数の詳しい解説 Nov 18, 2023 pm 03:08 PM

C++ のモード関数の詳細な説明 統計において、モードとは、一連のデータ内で最も頻繁に現れる値を指します。 C++ 言語では、モード関数を記述することによって、任意のデータセット内のモードを見つけることができます。モード関数はさまざまな方法で実装できます。一般的に使用される 2 つの方法を以下で詳しく紹介します。 1 つ目の方法は、ハッシュ テーブルを使用して各数値の出現回数をカウントすることです。まず、各数値をキー、出現回数を値とするハッシュ テーブルを定義する必要があります。次に、特定のデータセットに対して次を実行します。

Oracle SQLの除算演算の詳細説明 Oracle SQLの除算演算の詳細説明 Mar 10, 2024 am 09:51 AM

OracleSQL の除算演算の詳細な説明 OracleSQL では、除算演算は一般的かつ重要な数学演算であり、2 つの数値を除算した結果を計算するために使用されます。除算はデータベース問合せでよく使用されるため、OracleSQL での除算演算とその使用法を理解することは、データベース開発者にとって重要なスキルの 1 つです。この記事では、OracleSQL の除算演算に関する関連知識を詳細に説明し、読者の参考となる具体的なコード例を示します。 1. OracleSQL での除算演算

C++の剰余関数の詳しい解説 C++の剰余関数の詳しい解説 Nov 18, 2023 pm 02:41 PM

C++ の剰余関数の詳しい説明 C++ では、剰余演算子 (%) を使用して、2 つの数値を除算した余りを計算します。これは、オペランドが任意の整数型 (char、short、int、long など) または浮動小数点数型 (float、double など) になる二項演算子です。剰余演算子は、被除数と同じ符号の結果を返します。たとえば、整数の剰余演算の場合、次のコードを使用して実装できます。

Vue.nextTick関数の使い方と非同期更新での応用について詳しく解説 Vue.nextTick関数の使い方と非同期更新での応用について詳しく解説 Jul 26, 2023 am 08:57 AM

Vue.nextTick 関数の使い方と非同期更新での応用について詳しく説明 Vue の開発では、DOM を変更した直後にデータを更新したり、関連する操作が必要になったりするなど、データを非同期で更新する必要がある状況によく遭遇します。データが更新された直後に実行されます。このような問題を解決するために登場したのが、Vue が提供する .nextTick 関数です。この記事では、Vue.nextTick 関数の使用法を詳しく紹介し、コード例と組み合わせて、非同期更新でのアプリケーションを説明します。 1.Vue.nex

PHPモジュロ演算子の役割と使い方を詳しく解説 PHPモジュロ演算子の役割と使い方を詳しく解説 Mar 19, 2024 pm 04:33 PM

PHP のモジュロ演算子 (%) は、2 つの数値を除算した余りを取得するために使用されます。この記事では、モジュロ演算子の役割と使用法について詳しく説明し、読者の理解を深めるために具体的なコード例を示します。 1. モジュロ演算子の役割 数学では、整数を別の整数で割ると、商と余りが得られます。たとえば、10 を 3 で割ると、商は 3 になり、余りは 1 になります。モジュロ演算子は、この剰余を取得するために使用されます。 2. モジュロ演算子の使用法 PHP では、% 記号を使用してモジュロを表します。

php-fpmのチューニング方法を詳しく解説 php-fpmのチューニング方法を詳しく解説 Jul 08, 2023 pm 04:31 PM

PHP-FPM は、PHP のパフォーマンスと安定性を向上させるために一般的に使用される PHP プロセス マネージャーです。ただし、高負荷環境では、PHP-FPM のデフォルト設定ではニーズを満たせない場合があるため、チューニングが必要です。この記事では、PHP-FPM のチューニング方法を詳しく紹介し、いくつかのコード例を示します。 1. プロセスの数を増やす デフォルトでは、PHP-FPM はリクエストを処理するために少数のプロセスのみを開始します。高負荷環境では、プロセス数を増やすことで PHP-FPM の同時実行性を高めることができます。

Linuxシステムコールsystem()関数の詳細説明 Linuxシステムコールsystem()関数の詳細説明 Feb 22, 2024 pm 08:21 PM

Linux システム コール system() 関数の詳細説明 システム コールは、Linux オペレーティング システムの非常に重要な部分であり、システム カーネルと対話する方法を提供します。その中でも、system()関数はよく使われるシステムコール関数の一つです。この記事では、system() 関数の使用法を詳しく紹介し、対応するコード例を示します。システム コールの基本概念 システム コールは、ユーザー プログラムがオペレーティング システム カーネルと対話する方法です。ユーザープログラムはシステムコール関数を呼び出してオペレーティングシステムを要求します。

See all articles