日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

BEA 實(shí)戰(zhàn)集錦-探查 Struts 與 WebLogic Server 共用問題

 funronglei 2006-11-18

探查 Struts 與 WebLogic Server 共用問題

問題描述
Struts 是 JAVA 和 J2EE 界最普及、使用最廣泛的 MVC 框架之一。自誕生以來,Struts 就以其將業(yè)務(wù)邏輯與表示邏輯分離的清晰視點(diǎn)給業(yè)界留下了深刻印象。本模式將介紹常見錯(cuò)誤及解決方法。
 
故障排除
調(diào)試 Struts 應(yīng)用程序時(shí),故障排除可能錯(cuò)綜復(fù)雜,因?yàn)橛袝r(shí)錯(cuò)誤信息所指示的原因并非錯(cuò)誤的真正成因。有時(shí)可能甚至不出現(xiàn)任何錯(cuò)誤。

請注意,并非下面所有任務(wù)都需要完成。有些問題僅通過執(zhí)行幾項(xiàng)任務(wù)就可以解決。

快速鏈接:

任何 Struts 配置的大多數(shù)問題都可能是因配置問題所致,多半可能是配置不正確。因此,確保配置沒有問題很重要。


更正應(yīng)用程序文件
Struts 1.1 將許多公用類從 struts.jar 中分離出來。大多數(shù)公用功能(如 digestor 實(shí)用程序和 Bean 實(shí)用程序)已移至公用包中。需要將 commons jar 隨 Struts 實(shí)現(xiàn)類一起引用。Struts 實(shí)現(xiàn)類中已廣泛使用 commons 類。

如果不想遭遇那些惱人的 NoClassDefFound 錯(cuò)誤,就需要確保 Struts Web 應(yīng)用程序始終包含下列包。


包名稱
用途

commons-beanutils.jar

簡單易用的 Java 反射和內(nèi)省 API 包裝器

commons-collections.jar

一組用于擴(kuò)展和增強(qiáng) Java Collections Framework 的類

commons-digester.jar

通常用于分析 XML 配置文件的 XML 到 Java 對象映射實(shí)用程序

commons-lang.jar

一組公用實(shí)用程序類,可以為 java.lang 中的類提供附加功能

commons-logging.jar

各種日志 API 實(shí)現(xiàn)的包裝器

commons-validator.jar

用于定義 XML 文件中的驗(yàn)證類(驗(yàn)證方法)和驗(yàn)證規(guī)則的可擴(kuò)展框架

jakarta-oro.jar

一組文本處理 Java 類,可以提供兼容 Perl 5 的正則表達(dá)式


備注:如果從 Struts 1.0 升級到 Struts 1.1,digestor 類將以單獨(dú)包的形式位于公用項(xiàng)目下。在 Struts 1.0 中,digestor 類是 Struts 源代碼的一部分。

對于任何 Struts 應(yīng)用程序,類路徑中必須有上述類。

返回頁首


理解 Struts 配置文件
通過一個(gè)基于 XML 的配置文件來記錄和控制 Struts 配置。缺省情況下,該文件的名稱是 struts-config.xml,位于 Web 應(yīng)用程序的 WEB-INF 目錄中。Struts 有一個(gè)中央控制器 Servlet (org.apache.struts.action.ActionServlet),首次加載 Struts 應(yīng)用程序時(shí),它會對該配置文件進(jìn)行分析。 

該配置文件包含 Action 類與 Form 類的映射。映射為應(yīng)用程序提供頁面流。因此,配置文件的兩個(gè)重要部分是 <form-beans><action-mappings>。

  • 下面是一個(gè)示例 form-bean
    <form-beans>

    <form-bean
    name="LoginForm"

    type="com.test.LoginForm"/>


    </form-beans>
  • 對應(yīng)的 action-mapping 是這樣的:
    <action-mappings>

    <action
    path="/login"
    type="com.test.LoginAction"
    name="LoginForm"
    scope="request"
    validate="true"
    input="/pages/Login.jsp"/>


    </action-mappings>

合并后的應(yīng)用程序流是這樣的:

如果 Struts 配置文件中提供的配置詳細(xì)信息正確,Struts 控制器會對該應(yīng)用程序流實(shí)施控制。如果提供的路徑不正確或未在類加載器中找到 Form Bean 或 Action Bean,控制器將返回運(yùn)行時(shí)錯(cuò)誤。

返回頁首


Struts Form Bean

那么,準(zhǔn)確地講什么是 Form Bean 呢?Form Bean 是一種 Java Bean,廣泛用于映射 HTML 表單與相應(yīng)的 Java Bean。Form Bean 的編碼和使用都很簡單。在使用 Form Bean 時(shí),需要密切注意以下幾點(diǎn):

  1. Form Bean 映射到的是 HTML 表單上的元素或控件。例如,如果 HTML 表單包含名為 name 的字段,F(xiàn)orm Bean 就會包含名為 name 的屬性。

  2. 在映射到 HTML 控件的 Form Bean 中定義的每個(gè)屬性都必須有與之對應(yīng)的賦值方法和取值方法。例如,該屬性有兩個(gè)方法:setName()getName()。 

  3. Form Bean 還包含一個(gè)名為 validate() 的方法??梢允褂?validate 方法驗(yàn)證表單項(xiàng),如果驗(yàn)證失敗,則填充 actionErrors 對象,并將控制權(quán)返還給調(diào)用頁面,隨后調(diào)用頁面會顯示這些錯(cuò)誤。下一小節(jié)將對驗(yàn)證和錯(cuò)誤處理做更多介紹。

返回頁首

Action

Action 類主要用于處理來自視圖的數(shù)據(jù)和對該數(shù)據(jù)執(zhí)行任何業(yè)務(wù)操作。Action 類是 org.apache.struts.action.Action(其實(shí)就是一個(gè) HttpServlet)的擴(kuò)展。因此實(shí)際上是在執(zhí)行 Servlet。 

這些 action 類與 Servlet 不同,它們不是在 web.xml 中注冊,而是映射到 Struts 配置文件中的 action 表單。其類似于以下代碼:

<action
path="/login"
type="com.test.LoginAction"
name="LoginForm"
scope="request"
validate="true"
input="/pages/Login.jsp"/>

 

可以使用其中的 path 屬性 "/login" 調(diào)用 Servlet。

Action 類定義需要先行覆蓋,才能執(zhí)行任何任務(wù)的 execute 方法。Execute 方法有權(quán)訪問對應(yīng)視圖的 actionForm Bean、對整個(gè) Struts 配置的引用、HttpServletRequest 對象及 HttpServletResponse 對象。這使 execute 方法能夠?qū)?font style="FONT-FAMILY: courier new" size=-1> HttpSession 對象、HttpSelvletRequest 對象及 HttpServletResponse 對象執(zhí)行操作。

 

public ActionForward execute(ActionMapping mapping,
                                                        ActionForm form, 
                                                       HttpServletRequest request, 
                                                       HttpServletResponse response)

 

備注:在 Struts 1.0 中,該方法的名稱是 perform()。Struts 1.1 已不支持該方法。

Action 類返回 ActionForward 對象。此 ActionForward 對象確定需要將請求發(fā)送到的正確視圖。還會在 Struts 配置文件中注冊需要將控制權(quán)轉(zhuǎn)交給的正確視圖。 

在上例中,假定在登錄失敗時(shí)需要將控制權(quán)傳遞給 error.jsp,在登錄成功時(shí)需要將控制權(quán)傳遞給 nextPage.jsp。Forward 標(biāo)記的注冊方式如下:

 

<action
path="/login"
type="com.test.LoginAction"
name="LoginForm"
scope="request"
validate="true"
input="/pages/Login.jsp">
<forward 
    name="failure" 
    path="/error.jsp"/>
<forward 
    name="success" 
    path="/nextPage.jsp"/>
</action>

 

Execute 方法通常以下列語句作為結(jié)束語句。

return (mapping.findForward("failure"));

其中的 mapping 指的是 ActionMapping 對象。已定義了特定 action 的 "failure" 路徑。因此以上語句實(shí)際執(zhí)行的操作是將請求發(fā)送給 error.jsp。  

以上示例中的 <forward> 標(biāo)記具有局部作用域,可以在定義時(shí)所針對的 action 內(nèi)使用。但也可以定義全局 forward。全局 forward 也在 Struts 配置文件中定義,這與任何其它配置信息是一樣的。正如定義全局變量那樣,全局 forward 可以在應(yīng)用程序中的任何地方使用。 


 

<global-forwards>
<forward
name="welcome"
path="/Welcome.jsp"/>
</global-forwards>

 

因此,可以在應(yīng)用程序中的任何地方使用 mapping.findForward("welcome"),而它始終會將控制權(quán)轉(zhuǎn)交給 Welcome.jsp。

返回頁首


Validate 方法和錯(cuò)誤處理
如前所述,可以在 struts-config.xml 中禁用操作和驗(yàn)證。Action 中央控制器將確保不進(jìn)行驗(yàn)證。 


 

<action
path="/login"
type="com.test.LoginAction"
name="LoginForm"
scope="request"
validate="true"
input="/pages/Login.jsp"/>

 

Validate 方法返回 ActionErrors 對象。這些對象充當(dāng)錯(cuò)誤信息的容器。如果驗(yàn)證失敗,將把這些對象返還給調(diào)用 JSP,它可以處理對象以顯示它們。

返回頁首


排除消息資源故障
消息資源幫助開發(fā)人員在一個(gè)集中位置存儲標(biāo)簽、錯(cuò)誤信息等內(nèi)容,簡化了后續(xù)階段的維護(hù)工作。該集中位置是一個(gè)屬性文件,存儲在應(yīng)用程序的類路徑中,因此組件可以方便地訪問。

以下是為 Struts 應(yīng)用程序定義消息資源的兩種方法:

  • web.xml 
  • struts-config.xml

對于 web.xml,將屬性文件定義為 ActionServlet 的 param-value。下面是一個(gè)簡短的示例:


<servlet>
<servlet-name>action</servlet -name>
<servlet-class>
    org.apache.struts.action .ActionServlet
</servlet-class>
<init-param>
<param-name>
    application
</param-name>
<param-value>
   beatest.ApplicationResources
</param-value>
</init-param>
</servlet>

請注意,param-name 應(yīng)用程序和值表示為beatest.ApplicationResources這表示在應(yīng)用程序類路徑的包 beatest 內(nèi)一定存在一個(gè)名為 ApplicationResources.properties 的屬性文件。

在 Struts 1.1 中,可以在 struts-config.xml 中定義資源包。

<message-resources parameter="beatest.ApplicationResources"/>

此處的參數(shù)為必需值,它引用類路徑 beatest 包中的 ApplicationResources.properties 文件。使用 Struts 1.1 時(shí)可以有多個(gè)資源包,這使開發(fā)人員還能夠?qū)Y源包進(jìn)行組織。例如,可以有這樣的包:

<message-resources key=”errorBundle”  parameter="beatest.ApplicationErrors"/>

<message-resources key=”labelsBundle”  parameter="beatest.ApplicationLabels"/>

可以在應(yīng)用程序中對它們進(jìn)行適當(dāng)設(shè)置。如果用戶想要為 HTML 顯示標(biāo)簽,則可以使用 labelsBundle

<bean:message bundle="lablesBundle" key="some.message.key"/>

而如果想要顯示錯(cuò)誤信息,則可以使用 errorBundle。

<bean:message bundle="errorBundle" key="some.error.message"/>

返回頁首

使用消息資源時(shí)的常見問題
開發(fā) Struts 應(yīng)用程序過程中的一個(gè)常見錯(cuò)誤是:

 javax.servlet.jsp.JspException:Missing message for key "<some key name>"

要解決此問題,可以確認(rèn)是否存在下列情況:

  • 消息不是從正確的資源包取得的。請確保引用的是真正包含所提及的鍵的正確的資源包。 

  • 資源屬性文件不在正確的位置或不在應(yīng)用程序的類路徑中。應(yīng)用程序資源屬性文件應(yīng)位于 WEB-INF\classes 目錄中,或應(yīng)為 WEB-INF\lib 目錄中某個(gè) .jar 文件的一部分。 

  •  使用 null="false" 可避免上述錯(cuò)誤。例如:

     <bean:message bundle="lablesBundle" key="some.message.key" null="false">

    這樣將會設(shè)置一個(gè)消息資源包,在文件 MyWebAppResources.properties 的缺省鍵下提供該資源包。缺少的資源鍵將顯示為“???keyname???”。 

返回頁首


排除 Struts 國際化故障
缺省情況下,Struts 在每個(gè)用戶的會話中提供一個(gè) Locale 對象??梢愿鶕?jù)用戶提供的信息對此 Locale 對象做適當(dāng)設(shè)置。 

以下是 Struts 國際化檢查清單:

  1. 設(shè)置了 Locale Servlet 參數(shù)。
    確保將 ActionServlet 的 Locale 參數(shù)設(shè)置為 true。缺省情況下將此參數(shù)設(shè)置為 true,即缺省情況下啟用本地化。

  2. 使用了正確的應(yīng)用程序資源 Servlet 參數(shù)。
    對于 MessageResource,如果指定了正確的語言環(huán)境,則 ActionServlet 將在類路徑中尋找該語言環(huán)境專用的屬性文件。例如,如果像下面這樣指定 MessageResource: 

    <message-resources parameter="beatest.ApplicationResources"/>

    對語言環(huán)境敏感的應(yīng)用程序?qū)ふ颐Q為 ApplicationResources_xx_XX.properties 的文件,其中 xx_XX 為特定的語言環(huán)境,如 es_USfr_CA

    該屬性文件只不過是一個(gè)簡單的包含一組鍵值對的文本文件。用戶需要確保文件的名稱正確并位于類路徑中。建議將該文件置于 Web 應(yīng)用程序的 WEB-INF/classes 目錄中。 

  3. 如果用戶不在缺省語言環(huán)境中,則可以在 ActionServlet 中更改 Locale 對象??梢酝ㄟ^替換會話中的 Locale 對象進(jìn)行更改。 

    Locale locale = new Locale("English","US");
    session.setAttribute(Action.LOCALE_KEY,locale); 

  4. 如果使用了 Struts 控制器,則可以在 struts-config.xml 中將語言環(huán)境指定為控制器聲明的一部分。 

    <controller processorClass="org.apache.struts.action.RequestProcessor" debug="2" locale="fr_CA"/>

返回頁首


調(diào)試和日志記錄 Struts 應(yīng)用程序
WebLogic 提供了它自己的日志子系統(tǒng),該系統(tǒng)是 WebLogic 的缺省日志框架。不過,也可以將 WebLogic 與其它日志框架(如 Log4j)一起使用。缺省情況下,Struts 將把所有消息記錄到 WebLogic 日志框架。要在開發(fā) Struts 應(yīng)用程序過程中進(jìn)行最有效的記錄日志,需要確保將“Logging Message”嚴(yán)重性設(shè)置為“INFO”。


這樣一來,將報(bào)告所有正常和異常操作,從而可以在出錯(cuò)時(shí)進(jìn)行有效的調(diào)試。有關(guān)詳細(xì)信息,請參考 http://e-docs./wls/docs81/ConsoleHelp/logging.html#1055676 (English)。

還建議將所有 system.out.println() 消息都重定向到 WebLogic 日志,以方便調(diào)試。可以指定記錄這些消息的 stdout 文件。只需編輯 WebLogic Server 腳本,使 JAVA_OPTIONS 變量做以下指定:

-Dweblogic.Stdout="stdout-filename"
-Dweblogic.Stderr="stderr-filename"

有關(guān)詳細(xì)信息,請參考 http://e-docs./wls/docs81/ConsoleHelp/logging.html#1062846 (English)。

要查看所有發(fā)出的 HTTP 請求的日志,可以參考 WebLogic Server 生成的訪問日志。該日志提供了訪問的所有請求連同時(shí)間戳和訪問的 URL 連同 HTTP 返回代碼的詳細(xì)信息。

例如,訪問日志將提供如下信息:

127.0.0.1 - - [13/Jul/2004:21:39:46 -0615] "GET /struts-sample/preregisterCab.do?IndiReport
=true HTTP/1.1" 200 4173 
127.0.0.1 - - [13/Jul/2004:21:41:14 -0615] "POST /struts-sample/getIndiData.do;jsessionid=A05R5lY5jLRJokg8BRMYgLwCOvfuVzC7KEE4AsCZijq
D7l6A22Re!-237055073 HTTP/1.1" 200 4667 
127.0.0.1 - - [16/Jul/2004:00:07:58 -0615] "GET /struts-sample/preregisterCab.do?IndiReport
=true HTTP/1.1" 200 4173 
127.0.0.1 - - [16/Jul/2004:00:08:26 -0615] "POST /struts-sample/getIndiData.do;jsessionid=A32LikMTeXrS5Bnbp7p1TASmcLHkuko9Sudr8Lja
tWw2AqeP6zkt!1759102893 HTTP/1.1" 200 8893 
127.0.0.1 - - [19/Jul/2004:04:39:36 -0615] "GET /struts-sample/preregisterCab.do?IndiReport
=true HTTP/1.1" 200 4173 
127.0.0.1 - - [19/Jul/2004:04:40:16 -0615] "POST /struts-sample/getIndiData.do;jsessionid=A7yxT3KtTy01T7A39DLSup2RPqxvV9uWay325WxB
Lqtj1dlx3Ewa!-431463598 HTTP/1.1" 200 5416 
127.0.0.1 - - [14/Aug/2004:22:36:24 -0615] "GET /struts-sample/preregisterCab.do?IndiRepor
t=true HTTP/1.1" 200 4173 
127.0.0.1 - - [14/Aug/2004:22:36:58 -0615] "POST /struts-sample/getIndiData.do;jsessionid=Be2WKm1nP7DGdX1uIY8PraQdx51wBZTjVSswGHdcbL4njcj
XOdJh!1670519755 HTTP/1.1" 200 4684 
127.0.0.1 - - [14/Aug/2004:22:36:59 -0615] "GET /struts-sample/pages/STFull.jpg HTTP/1.1" 304 0

有關(guān)如何控制 HTTP 日志的詳細(xì)信息,請參考下列鏈接: 建議的有關(guān) WebLogic 記錄功能的閱讀材料:

返回頁首


Struts 應(yīng)用程序內(nèi)的擴(kuò)展日志記錄 

  1. ActionServletweb.xml 中使用調(diào)試級別來確保獲得擴(kuò)展的調(diào)試消息。有效的 debug 值是 0(不記錄)到 6(最嚴(yán)重)。 

  2. 將 detail 參數(shù)設(shè)置為調(diào)試來自 digestor 的消息。以下是 web.xml 的一個(gè)片斷。

    <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
    <param-name>config</param-name>
    <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <init-param>
    <param-name>debug</param-name>
    <param-value>4</param-value>
    </init-param>
    <init-param>
    <param-name>detail</param-name>
    <param-value>2</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
    </servlet>
    請注意其中的 debug 和 detail 級別。 

     

  3. 如果使用缺省的 RequestProcesor 控制器,請對附加調(diào)試消息使用控制器的 debug 參數(shù)。以下是 struts-config.xml 的一個(gè)片斷。
    <controller processorClass="org.apache.struts.action.RequestProcessor" debug="2"/>

返回頁首


調(diào)試 WebLogic 類加載器
在開發(fā) Struts 應(yīng)用程序的過程中,必然會遇到類加載器問題。調(diào)試那些 NoClassDefFoundErrorClassNotFoundException 的確是一件麻煩事。 


類加載器和 WebLogic Server 類加載簡介

與 Java 的類繼承相似,類加載器具有由父類加載器(相當(dāng)于超類)和子類加載器(相當(dāng)于子類)構(gòu)成的層次結(jié)構(gòu)。

啟動(dòng)類加載器是 Java 類加載器層次結(jié)構(gòu)的父級。Java 虛擬機(jī)創(chuàng)建此類加載器,然后由它加載 JDK 內(nèi)部類以及 Java 虛擬機(jī)中包括的 java.* 包。例如,java.lang.String 是由啟動(dòng)類加載器加載的。

擴(kuò)展類加載器是啟動(dòng)類加載器的子級。它加載置于 JDK 的 extensions 目錄中的所有 jar 文件。這是一種在不向類路徑中添加條目的情況下擴(kuò)展 JDK 的便捷手段。不過,extensions 目錄中的任何內(nèi)容都必須是獨(dú)立的。它只能引用 extensions 目錄中的類或 JDK 類中的類。JDK 擴(kuò)展加載器是由系統(tǒng)類路徑類加載器擴(kuò)展而來。大多數(shù) Java 程序員都熟悉這個(gè)類加載器。它加載 Java 虛擬機(jī)類路徑中的類。應(yīng)用程序特定的類加載器(如 WebLogic Server 創(chuàng)建的類加載器)是系統(tǒng)類路徑類加載器的子級。

WebLogic Server 的類加載以應(yīng)用程序概念為中心。應(yīng)用程序通常是包含應(yīng)用程序類的 EAR(企業(yè)歸檔)文件。EAR 文件中的所有內(nèi)容都將被視為同一應(yīng)用程序的一部分。較小的應(yīng)用程序可能是 EJB jar 文件或 Web 應(yīng)用程序 (WAR) 文件。請注意,如果分別部署 EJB jar 文件和 Web 應(yīng)用程序 war 文件,則會將它們視為兩個(gè)應(yīng)用程序。如果將它們共同部署在一個(gè) EAR 文件內(nèi),則將它們視為一個(gè)應(yīng)用程序。每個(gè)應(yīng)用程序均容納其自身的類加載器層次結(jié)構(gòu),該結(jié)構(gòu)的父級為系統(tǒng)類路徑類加載器。這樣就將各應(yīng)用程序隔離開來,使應(yīng)用程序 1 無法看到應(yīng)用程序 2 的類加載器或類。類加載器中沒有同級或友元的概念。應(yīng)用程序類加載器只能看到它們的父類加載器,即系統(tǒng)類路徑類加載器。這使 WebLogic Server 可以在同一個(gè) Java 虛擬機(jī)內(nèi)托管多個(gè)相互隔離的應(yīng)用程序。


無法在父類加載器和子類加載器中找到類時(shí),會發(fā)生 ClassNotFoundException。這很可能是打包問題造成的。 

加載了請求的類但無法找到依賴類時(shí),會拋出 NoClassDefFoundError。父類加載器中的類從不引用子類加載器中的類。類加載器會先請求它們的父類加載器加載類,然后才會嘗試自行加載類,因此在此類情況下可能會遇到 NoClassDefFoundError。  

為調(diào)試 WebLogic 類加載器,WebLogic 提供了類加載器特定的調(diào)試標(biāo)志。設(shè)置這些調(diào)試標(biāo)志的方法: 

  1. 編輯 StartWeblogic 腳本,添加以下內(nèi)容作為啟動(dòng) WebLogic 時(shí)的命令行參數(shù)。
    Dweblogic.Debug = debug.lineNumbers,debug.methodNames,weblogic.ClassLoaderVerbose,weblogic.ClassLoader

  2. 確保在控制臺的“Logging”選項(xiàng)中將“Debug to Stdout”選項(xiàng)設(shè)置為“enabled”。
啟用這些調(diào)試選項(xiàng)后,您就會注意到應(yīng)用程序?qū)ふ业娜魏晤惗紝⒂邢鄳?yīng)的以下日志。
[GenericClassLoader] : Looking for class: org.apache.struts.taglib.html.ImgTag...
With classpath of : ()
Classloader object id (weblogic.utils.classloaders.GenericClassLoader@127f79d finder: weblogic.utils.classloaders.MultiClassFinder@18353cf annotation: )
[GenericClassLoader] : Class org.apache.struts.taglib.html.ImgTag not found.
[GenericClassLoader] : Looking for class: org.apache.struts.taglib.html.ImgTag...
With classpath of : ()
Classloader object id (weblogic.utils.classloaders.GenericClassLoader@17d03c5 fi
nder: weblogic.utils.classloaders.MultiClassFinder@f37a62 annotation: Applicatio
nClassLoader@)
[GenericClassLoader] : Class org.apache.struts.taglib.html.ImgTag not found.
[GenericClassLoader] : Looking for class: org.apache.struts.taglib.html.ImgTag...
With classpath of : (C:\APP-INF\classes)
Classloader object id (weblogic.utils.classloaders.GenericClassLoader@17447c5 finder: weblogic.utils.classloaders.MultiClassFinder@e7eec9 annotation: struts-example@)
[GenericClassLoader] : Class org.apache.struts.taglib.html.ImgTag not found.
[ChangeAwareClassLoader] : weblogic.utils.classloaders.ChangeAwareClassLoader@165d0e0 finder: weblogic.utils.classloaders.MultiClassFinder@edd9de annotation: struts-example@struts-example about to loadClass(org.apache.struts.taglib.html.Img
Tag)
[GenericClassLoader] : Looking for class: org.apache.struts.taglib.html.ImgTag..
.
With classpath of : (C:\bea-plat-81sp3\user_projects\domains\sqlservdomain\myserver\.wlnotdelete\extract\myserver_struts-example_struts-example\jarfiles\WEB-INF
\lib\log4j.jar;C:\bea-plat-81sp3\user_projects\domains\sqlservdomain\myserver\.w
lnotdelete\extract\myserver_struts-example_struts-example\jarfiles\WEB-INF\lib\log4j-core.jar)
Classloader object id (weblogic.utils.classloaders.ChangeAwareClassLoader@165d0e0 finder: weblogic.utils.classloaders.MultiClassFinder@edd9de annotation: struts-example@struts-example)
[GenericClassLoader] : Found class: org.apache.struts.taglib.html.ImgTag
[GenericClassLoader] : weblogic.utils.classloaders.ChangeAwareClassLoader@165d0e0 finder: weblogic.utils.classloaders.MultiClassFinder@edd9de annotation: struts-example@struts-example defined class class org.apache.struts.taglib.html.ImgTag

請注意,上例中 Struts 應(yīng)用程序?qū)ふ业氖?org.apache.struts.taglib.html.ImgTag 類。首先在父類加載器中尋找該類,然后在應(yīng)用程序加載器中尋找,最后在 war 類加載器中尋找。

返回頁首

如果在類加載器中找不到某個(gè)類,您會注意到日志中產(chǎn)生了下面這樣的消息。

[GenericClassLoader] : Looking for class: org.apache.struts.taglib.html.ImgTag...
With classpath of : ()
Classloader object id (weblogic.utils.classloaders.GenericClassLoader@10d3f0d finder: weblogic.utils.classloaders.MultiClassFinder@1510d96 annotation: )
[GenericClassLoader] : Class org.apache.struts.taglib.html.ImgTag not found.
[GenericClassLoader] : Looking for class: org.apache.struts.taglib.html.ImgTag...
With classpath of : ()
Classloader object id (weblogic.utils.classloaders.GenericClassLoader@1ce64f6 finder: weblogic.utils.classloaders.MultiClassFinder@52fecf annotation: ApplicationClassLoader@)
[GenericClassLoader] : Class org.apache.struts.taglib.html.ImgTag not found.
[GenericClassLoader] : Looking for class: org.apache.struts.taglib.html.ImgTag...
With classpath of : (C:\APP-INF\classes)
Classloader object id (weblogic.utils.classloaders.GenericClassLoader@1d6d61d finder: weblogic.utils.classloaders.MultiClassFinder@d6ee28 annotation: struts-example@)
[GenericClassLoader] : Class org.apache.struts.taglib.html.ImgTag not found.
[ChangeAwareClassLoader] : weblogic.utils.classloaders.ChangeAwareClassLoader@18a6890 finder: weblogic.utils.classloaders.MultiClassFinder@ad8bb4 annotation: struts-example@struts-example about to loadClass(org.apache.struts.taglib.html.ImgTag)
[GenericClassLoader] : Looking for class: org.apache.struts.taglib.html.ImgTag...
With classpath of : (C:\bea-plat-81sp3\user_projects\domains\sqlservdomain\myserver\.wlnotdelete\extract\myserver_struts-example_struts-example\jarfiles\WEB-INF
\lib\log4j.jar;C:\bea-plat-81sp3\user_projects\domains\sqlservdomain\myserver\.w
 

lnotdelete\extract\myserver_struts-example_struts-example\jarfiles\WEB-INF\lib\log4j-core.jar)
Classloader object id (weblogic.utils.classloaders.ChangeAwareClassLoader@18a689
0 finder: weblogic.utils.classloaders.MultiClassFinder@ad8bb4 annotation: struts
-example@struts-example)
[GenericClassLoader] : Class org.apache.struts.taglib.html.ImgTag not found.
<Nov 17, 2004 4:37:52 PM PST> <Error> <HTTP> <BEA-101017> <[ServletContext(id=28746180,name=struts-example,context-path=/struts-example)] Root cause of ServletException.
java.lang.NoClassDefFoundError: org/apache/struts/taglib/html/ImgTag
at jsp_servlet.__index._jspService(__index.java:434)
at weblogic.servlet.jsp.JspBase.service(JspBase.java:33)
at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:996)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:419)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:463)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:315)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run
(WebAppServletContext.java:6452)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:118)
at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3661)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2630)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:219)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:178)

請注意,在所有可能的類加載器中搜索類未果后,發(fā)生了 NoClassDefFoundError 錯(cuò)誤。 

如果將 EJB 與 Struts 應(yīng)用程序一起使用,則應(yīng)使用 Ear(企業(yè)歸檔)格式打包應(yīng)用程序。雖然可以分別部署 WAR 和 JAR 文件,但如果將它們共同部署在一個(gè) EAR 文件中,則所形成的類加載器排布將使 Servlet 和 JSP 能夠找到 EJB 類。

類加載器結(jié)構(gòu)是這樣的:


請注意,EJB 類加載器現(xiàn)在是 Web 應(yīng)用程序的父類加載器。

返回頁首

如果 EJB 和 Web 應(yīng)用程序使用公用類,將遇到以下兩種可能的情況:

  1. 需要維護(hù)重復(fù)類
  2. 使用 manifest 文件提供不同類加載器間共享類的類路徑

WebLogic 8.1 推出了為“Enterprise Archive”使用 APP-INF 這一方案來解決上述問題。將實(shí)用程序 JAR 文件置于 APP-INF/lib 目錄中,將各個(gè)類置于 APP-INF/classes 目錄中。將把這些類加載到應(yīng)用程序的根類加載器中,從而使 Struts 應(yīng)用程序和 EJB 都能夠訪問。  

備注:只有 WebLogic 8.1 和以上版本中才提供 APP-INF 功能。對于 WebLogic 8.1 之前的版本,建議的方法是使用表明文件選項(xiàng)。

有關(guān)類加載器在 WebLogic Server 中的工作方式的詳細(xì)說明,請參考下列鏈接:

  1. WebLogic Server Appliation Classloading (English)
  2. JAR File Specification

返回頁首


Struts 應(yīng)用程序性能問題

  • 為對象使用適當(dāng)?shù)淖饔糜?/strong>
    避免使 HttpSession 膨脹,而應(yīng)評估在請求中存儲對象這一方案的可行性??梢詫⒉恍枰L時(shí)間持久存儲的對象作為 HttpSessionRequest 的一部分來存儲,這些對象用后即會被銷毀。作為一項(xiàng)慣例,應(yīng)將 JSP 中 useBean 標(biāo)記的作用域最小化。因此,Action 表單的子類不應(yīng)具有會話或應(yīng)用程序的作用域,除非已無其它方案可供選擇。 

  • gif 和 jpeg 數(shù)量過多
    站在用戶的角度看,其瀏覽器中頁面顯示的響應(yīng)時(shí)間取決于下載速度和頁面的復(fù)雜性。例如,圖形的數(shù)量。即使各單項(xiàng) Web 內(nèi)容的下載都相當(dāng)快,設(shè)計(jì)不佳的圖形極多的動(dòng)態(tài)網(wǎng)站也會讓人有“慢”的感覺。 

  • 預(yù)編譯 JSP
    預(yù)編譯 JSP 可以為首次訪問 Struts 應(yīng)用程序的用戶提供更好的性能。請使用 weblogic.appc(WLS 8.1 及更高版本)或 weblogic.jspc 來預(yù)編譯應(yīng)用程序。 

  • 刷新靜態(tài)頁面
    如果只修改了靜態(tài)文件,則可以刷新它們而不用重新部署整個(gè)應(yīng)用程序。請使用 weblogic.deployer 實(shí)用程序來完成此任務(wù)。請參考
    http://e-docs./wls/docs81/webapp/deployment.html (English)

  • 標(biāo)記庫過多
    實(shí)際上,Struts 框架本身就使用了大量標(biāo)記庫。除非不得已,建議在任何情況下都要最充分地利用這些現(xiàn)成的庫,而不要?jiǎng)?chuàng)建新庫。自定義標(biāo)記會產(chǎn)生性能開銷。請盡可能少用。

  • 使用 Servlet 過濾器
    這可能會成為性能開銷。請確認(rèn)它是否為應(yīng)用程序可接受的開銷。 

  • 充分調(diào)整 JVM
    請確保充分調(diào)整 JVM。有關(guān)如何調(diào)整 JVM 的更多詳細(xì)信息,請參考 http://e-docs./wls/docs81/perform/JVMTuning.html (English)。 

  • 將 EJB 與 Struts Web 應(yīng)用程序打包在一起
    避免在 WebLogic Server 上將 EJB 檔案與 Web 應(yīng)用程序作為獨(dú)立的、彼此無關(guān)的應(yīng)用程序進(jìn)行部署。如果客戶端在同一企業(yè)應(yīng)用程序內(nèi),WebLogic Server 會優(yōu)化 EJB 訪問。

返回頁首

Struts 最佳實(shí)踐

  1. 始終依據(jù) JSP 規(guī)范定義缺省錯(cuò)誤頁面。這樣如果在處理 Struts 頁面過程中出錯(cuò),將顯示錯(cuò)誤頁面而不是無任何內(nèi)容的空白屏幕。在 WebLogic 中,可以通過引用 http://e-docs./wls/docs81/webapp/web_xml.html#1017571 (English) 處的鏈接來設(shè)置錯(cuò)誤頁面。

  2. 使用 ExceptionHandler 來處理異常??梢栽?Struts-config 文件中聲明 ExceptionHandler??梢詫⒖刂茩?quán)傳遞給相應(yīng)的錯(cuò)誤處理程序頁面??梢栽谛枰獙⒖刂茩?quán)傳遞給非標(biāo)準(zhǔn)錯(cuò)誤頁面時(shí)使用它。 

  3. 將 EJB 與 Struts 一起使用時(shí),使用 Facade 模型調(diào)用 EJB。避免直接調(diào)用實(shí)體。避免將句柄緩存到無狀態(tài)會話 Bean 中。

  4. 建議不使用 Struts 數(shù)據(jù)源,而應(yīng)在進(jìn)行任何數(shù)據(jù)庫相關(guān)操作時(shí)使用 WebLogic 數(shù)據(jù)源,以利用 WebLogic 提供的連接池和事務(wù)控制功能。

  5. 仍處于開發(fā)階段時(shí),使用展開 war 格式部署應(yīng)用程序以節(jié)省開發(fā)時(shí)間。應(yīng)以開發(fā)模式啟動(dòng) WebLogic Server,以利用 WebLogic 提供的熱部署功能。

  6. 如果使用 EJB 和 Struts 應(yīng)用程序間共享的實(shí)用程序類簡化對實(shí)用程序類和實(shí)用程序檔案的打包,則請使用 WebLogic 8.1 提供的 APP-INF 功能。

  7. 不將應(yīng)用程序類添加到服務(wù)器的類路徑中。服務(wù)器處于運(yùn)行狀態(tài)時(shí),將無法更改服務(wù)器類路徑中的任何內(nèi)容。

返回頁首


WebLogic Server 已知問題
您可以定期查看所用 WLS 版本的“Release Notes”,了解 Service Pack 中的“Known Issues”或“Resolved Issues”的詳細(xì)信息及瀏覽 Weblogic Server 與 Struts 共用時(shí)的問題。方便起見,下面提供了這些發(fā)行說明的鏈接:

對于需要特別注意之處,請參閱以下 CR,在相應(yīng)版本 Service Pack 的發(fā)行說明中注明了已有針對它們的解決方法: 

  • CR109391 - 將不可序列化的對象置于 ServletContext 中時(shí),WebLogic Server 甚至嘗試也要將它們反序列化,結(jié)果導(dǎo)致 NotSerializableException。在 Welogic 7.0 SP5 (English) 中,此問題已得到解決。
  • CR134412 - 沒有為錯(cuò)誤頁面正確設(shè)置類加載器和環(huán)境上下文。在 WLS 8.1 SP3 (English) 中,此問題已得到解決。 
  • CR175651 - 問題成因是,在取消部署或重新部署 Web 應(yīng)用程序過程中,容器不等待進(jìn)行中的 webapp 請求完成。由此引發(fā)的問題是,如果某個(gè) Web 應(yīng)用程序依賴使用該上下文,取消部署后就會發(fā)生 NPE,因?yàn)樵撋舷挛囊巡辉儆行?。?WebLogic 8.1 SP4 (English) 中,此問題已得到解決。
使用搜索功能也可以搜索到“Release Notes”,還可以搜索到其它支持解決辦法及與 CR 有關(guān)的信息,如需要更多幫助?中所提到的內(nèi)容。如果客戶簽訂了技術(shù)支持合同,則可以登錄 http://support./,登錄后會看到為 Solutions 和 Bug Central 提供的 Browse portlet,可在其中按產(chǎn)品版本瀏覽最新提供的 CR。

返回頁首


外部資源

返回頁首


需要更多幫助?
如果您已經(jīng)理解這個(gè)模式,但仍需要更多幫助,您可以:
  1. http://support. 上查詢 AskBEA(例如,使用“investigating struts with weblogic server”),以查找其它已發(fā)布的解決辦法。技術(shù)支持合同客戶:確保已經(jīng)登錄,可以訪問提供的與 CR 有關(guān)的信息。
  2. http://newsgroups. 上,向 BEA 的某個(gè)新聞組提出更詳細(xì)具體的問題。

如果這還不能解決您的問題,并且您擁有有效的技術(shù)支持合同,您可以通過登錄以下網(wǎng)站來打開支持案例:http://support.。


反饋

請給我們提供您的意見,說明此支持診斷模式“探查 Struts 與 WebLogic Server 共用問題模式”一文是否有所幫助、您需要的任何解釋,以及對支持診斷模式的新主題的任何要求。


免責(zé)聲明

依據(jù) BEA 與您簽署的維護(hù)和支持協(xié)議條款,BEA Systems, Inc. 在本網(wǎng)站上提供技術(shù)技巧和補(bǔ)丁供您使用。雖然您可以將這些信息和代碼與您獲得 BEA 授權(quán)的軟件一起使用,但 BEA 并不對所提供的技術(shù)技巧和補(bǔ)丁做任何形式的擔(dān)保,無論是明確的還是隱含的。

本文檔中引用的任何商標(biāo)是其各自所有者的財(cái)產(chǎn)。有關(guān)完整的商標(biāo)信息,請參考您的產(chǎn)品手冊。

返回頁首

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多