国产成人久久精品亚洲小说,久久亚洲色一区二区三区,亚洲中文字幕日本无线码 http://m.tkk7.com/lanxin1020/category/38970.htmlzh-cnMon, 11 May 2009 09:55:39 GMTMon, 11 May 2009 09:55:39 GMT60struts-config.xml文件配置http://m.tkk7.com/lanxin1020/archive/2009/05/11/270067.htmllanxin1020lanxin1020Mon, 11 May 2009 08:26:00 GMThttp://m.tkk7.com/lanxin1020/archive/2009/05/11/270067.htmlhttp://m.tkk7.com/lanxin1020/comments/270067.htmlhttp://m.tkk7.com/lanxin1020/archive/2009/05/11/270067.html#Feedback0http://m.tkk7.com/lanxin1020/comments/commentRss/270067.htmlhttp://m.tkk7.com/lanxin1020/services/trackbacks/270067.html以下是一份完整的struts-config.xml文件,配置元素的說明詳見注釋.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config.dtd">
<!-- struts-config.xml中的元素必須按照上述doc指令中的dtd文檔定義順序書寫,本例即遵從了dtd定義順序 -->
<!-- struts-config是整個(gè)xml的根元素,其他元素必須被包含其內(nèi) -->
<struts-config>
<!--
   名稱:data-sources
   描述:data-sources元素定義了web App所需要使用的數(shù)據(jù)源
   數(shù)量:最多一個(gè)
   子元素:data-source
-->
<data-sources>
   <!--
    名稱:data-source
    描述:data-source元素定義了具體的數(shù)據(jù)源
    數(shù)量:任意多個(gè)
    屬性:
     @key:當(dāng)需要配置多個(gè)數(shù)據(jù)源時(shí),相當(dāng)于數(shù)據(jù)源的名稱,用來數(shù)據(jù)源彼此間進(jìn)行區(qū)別
     @type:可以使用的數(shù)據(jù)源實(shí)現(xiàn)的類,一般來自如下四個(gè)庫
      Poolman,開放源代碼軟件
      Expresso,Jcorporate
      JDBC Pool,開放源代碼軟件
      DBCP,Jakarta
   -->
   <data-source key="firstOne" type="org.apache.commons.dbcp.BasicDataSource">
    <!--
     名稱:set-property
     描述:用來設(shè)定數(shù)據(jù)源的屬性
     屬性:
      @autoCommit:是否自動(dòng)提交 可選值:true/false
      @description:數(shù)據(jù)源描述
      @driverClass:數(shù)據(jù)源使用的類
      @maxCount:最大數(shù)據(jù)源連接數(shù)
      @minCount:最小數(shù)據(jù)源連接數(shù)
      @user:數(shù)據(jù)庫用戶
      @password:數(shù)據(jù)庫密碼
      @url:數(shù)據(jù)庫url
    -->
    <set-property property="autoCommit" value="true"/>
    <set-property property="description" value="Hello!"/>
    <set-property property="driverClass" value="com.mysql.jdbc.Driver"/>
    <set-property property="maxCount" value="10"/>
    <set-property property="minCount" value="2"/>
    <set-property property="user" value="root"/>
    <set-property property="password" value=""/>
    <set-property property="url" value="jdbc:mysql://localhost:3306/helloAdmin"/>
   </data-source>
</data-sources>

<!--
   名稱:form-beans
   描述:用來配置多個(gè)ActionForm Bean
   數(shù)量:最多一個(gè)
   子元素:form-bean
-->
<form-beans>
   <!--
    名稱:form-bean
    描述:用來配置ActionForm Bean
    數(shù)量:任意多個(gè)
    子元素:form-property
    屬性:
     @className:指定與form-bean元素相對應(yīng)的配置類,一般默認(rèn)使用org.apaceh.struts.config.FormBeanConfig,如果自定義,則必須繼承 FormBeanConfig
     @name:必備屬性!為當(dāng)前form-bean制定一個(gè)全局唯一的標(biāo)識(shí)符,使得在整個(gè)Struts框架內(nèi),可以通過該標(biāo)識(shí)符來引用這個(gè)ActionForm Bean。
     @type:必備屬性!指明實(shí)現(xiàn)當(dāng)前ActionForm Bean的完整類名。
   -->
   <form-bean name="Hello" type="myPack.Hello">
    <!--
     名稱:form-property
     描述:用來設(shè)定ActionForm Bean的屬性
     數(shù)量:根據(jù)實(shí)際需求而定,例如,ActionForm Bean對應(yīng)的一個(gè)登陸Form中有兩個(gè)文本框,name和password,ActionForm Bean中也有這兩個(gè)字段,則此處編寫兩個(gè)form-property來設(shè)定屬性
     屬性:
      @className:指定與form-property相對應(yīng)的配置類,默認(rèn)是org.apache.struts.config.FormPropertyConfig,如果自定義,則必須繼承FormPropertyConfig類
      @name:所要設(shè)定的ActionForm Bean的屬性名稱
      @type:所要設(shè)定的ActionForm Bean的屬性值的類
      @initial:當(dāng)前屬性的初值
    -->
    <form-property name="name" type="java.lang.String"/>
    <form-property name="number" type="java.lang.Iteger" initial="18"/>
   </form-bean>
</form-beans>

<!--
   名稱:global-exceptions
   描述:處理異常
   數(shù)量:最多一個(gè)
   子元素:exception
-->
<global-exceptions>
   <!--
    名稱:exception
    描述:具體定義一個(gè)異常及其處理
    數(shù)量:任意多個(gè)
    屬性:
     @className:指定對應(yīng)exception的配置類,默認(rèn)為org.apache.struts.config.ExceptionConfig
     @handler:指定異常處理類,默認(rèn)為org.apache.struts.action.ExceptionHandler
     @key:指定在Resource Bundle種描述該異常的消息key
     @path:指定當(dāng)發(fā)生異常時(shí),進(jìn)行轉(zhuǎn)發(fā)的路徑
     @scope:指定ActionMessage實(shí)例存放的范圍,默認(rèn)為request,另外一個(gè)可選值是session
     @type:必須要有!指定所需要處理異常類的名字。
     @bundle:指定資源綁定
   -->
   <exception
    key=""hello.error
    path="/error.jsp"
    scope="session"
    type="hello.HandleError"/>
</global-exceptions>

<!--
   名稱:global-forwards
   描述:定義全局轉(zhuǎn)發(fā)
   數(shù)量:最多一個(gè)
   子元素:forward
-->
<global-forwards>
   <!--
    名稱:forward
    描述:定義一個(gè)具體的轉(zhuǎn)發(fā)
    數(shù)量:任意多個(gè)
    屬性:
     @className:指定和forward元素對應(yīng)的配置類,默認(rèn)為org.apache.struts.action.ActionForward
     @contextRelative:如果為true,則指明使用當(dāng)前上下文,路徑以“/”開頭,默認(rèn)為false
     @name:必須配有!指明轉(zhuǎn)發(fā)路徑的唯一標(biāo)識(shí)符
     @path:必須配有!指明轉(zhuǎn)發(fā)或者重定向的URI。必須以"/"開頭。具體配置要與contextRelative相應(yīng)。
     @redirect:為true時(shí),執(zhí)行重定向操作,否則執(zhí)行請求轉(zhuǎn)發(fā)。默認(rèn)為false
   -->
   <forward name="A" path="/a.jsp"/>
   <forward name="B" path="/hello/b.do"/>
</global-forwards>

<!--
   名稱:action-mappings
   描述:定義action集合
   數(shù)量:最多一個(gè)
   子元素:action
-->
<action-mappings>
   <!--
    名稱:action
    描述:定義了從特定的請求路徑到相應(yīng)的Action類的映射
    數(shù)量:任意多個(gè)
    子元素:exception,forward(二者均為局部量)
    屬性:
     @attribute:制定與當(dāng)前Action相關(guān)聯(lián)的ActionForm Bean在request和session范圍內(nèi)的名稱(key)
     @className:與Action元素對應(yīng)的配置類。默認(rèn)為org.apache.struts.action.ActionMapping
     @forward:指名轉(zhuǎn)發(fā)的URL路徑
     @include:指名包含的URL路徑
     @input:指名包含輸入表單的URL路徑,表單驗(yàn)證失敗時(shí),請求會(huì)被轉(zhuǎn)發(fā)到該URL中
     @name:指定和當(dāng)前Acion關(guān)聯(lián)的ActionForm Bean的名字。該名稱必須在form-bean元素中定義過。
     @path:指定訪問Action的路徑,以"/"開頭,沒有擴(kuò)展名
     @parameter:為當(dāng)前的Action配置參數(shù),可以在Action的execute()方法中,通過調(diào)用ActionMapping的getParameter()方法來獲取參數(shù)
     @roles:指定允許調(diào)用該Aciton的安全角色。多個(gè)角色之間用逗號(hào)分割。處理請求時(shí),RequestProcessor會(huì)根據(jù)該配置項(xiàng)來決定用戶是否有調(diào)用該Action的權(quán)限
     @scope:指定ActionForm Bean的存在范圍,可選值為request和session。默認(rèn)為session
     @type:指定Action類的完整類名
     @unknown:值為true時(shí),表示可以處理用戶發(fā)出的所有無效的Action URL。默認(rèn)為false
     @validate:指定是否要先調(diào)用ActionForm Bean的validate()方法。默認(rèn)為true
    注意:如上屬性中,forward/include/type三者相斥,即三者在同一Action配置中只能存在一個(gè)。
   -->
   <action path="/search"
    type="addressbook.actions.SearchAction"
    name="searchForm"
    scope="request"
    validate="true"
    input="/search.jsp">
    <forward name="success" path="/display.jsp"/>
   </action>  
</action-mappings>

<!--
   名稱:controller
   描述:用于配置ActionServlet
   數(shù)量:最多一個(gè)
   屬性:
    @bufferSize:指定上傳文件的輸入緩沖的大小.默認(rèn)為4096
    @className:指定當(dāng)前控制器的配置類.默認(rèn)為org.apache.struts.config.ControllerConfig
    @contentType:指定相應(yīng)結(jié)果的內(nèi)容類型和字符編碼
    @locale:指定是否把Locale對象保存到當(dāng)前用戶的session中,默認(rèn)為false
    @processorClass:指定負(fù)責(zé)處理請求的Java類的完整類名.默認(rèn)org.apache.struts.action.RequestProcessor
    @tempDir:指定文件上傳時(shí)的臨時(shí)工作目錄.如果沒有設(shè)置,將才用Servlet容器為web應(yīng)用分配的臨時(shí)工作目錄.
    @nochache:true時(shí),在相應(yīng)結(jié)果中加入特定的頭參數(shù):Pragma ,Cache-Control,Expires防止頁面被存儲(chǔ)在可數(shù)瀏覽器的緩存中,默認(rèn)為false
-->
<controller
   contentType="text/html;charset=UTF-8"
   locale="true"
   processorClass="CustomRequestProcessor">
</controller>
<!--
   名稱:message-resources
   描述:配置Resource Bundle.
   數(shù)量:任意多個(gè)
   屬性:
    @className:指定和message-resources對應(yīng)的配置類.默認(rèn)為org.apache.struts.config.MessageResourcesConfig
    @factory:指定資源的工廠類,默認(rèn)為org.apache.struts.util.PropertyMessageResourcesFactory
    @key:
    @null:
    @parameter:
-->
<message-resources
   null="false"
   parameter="defaultResource"/>
<message-resources
   key="images"
   null="false"
   parameter="ImageResources"/>
  
<!--
   名稱:plug-in
   描述:用于配置Struts的插件
   數(shù)量:任意多個(gè)
   子元素:set-property
   屬性:
    @className:指定Struts插件類.此類必須實(shí)現(xiàn)org.apache.struts.action.PlugIn接口
-->
<plug-in
   className="org.apache.struts.validator.ValidatorPlugIn">
   <!--
    名稱:set-property
    描述:配置插件的屬性
    數(shù)量:任意多個(gè)
    屬性:
     @property:插件的屬性名稱
     @value:該名稱所配置的值
   -->
   <set-property
    property="pathnames"
    value="/WEB-INF/validator-rules.xml,/WEB-INF/vlaidation.xml"/>
</plug-in>

</struts-config>



lanxin1020 2009-05-11 16:26 發(fā)表評論
]]>
擴(kuò)充struts驗(yàn)證框架,進(jìn)行多表單頁面的驗(yàn)證(轉(zhuǎn))http://m.tkk7.com/lanxin1020/archive/2009/05/09/269828.htmllanxin1020lanxin1020Sat, 09 May 2009 14:59:00 GMThttp://m.tkk7.com/lanxin1020/archive/2009/05/09/269828.htmlhttp://m.tkk7.com/lanxin1020/comments/269828.htmlhttp://m.tkk7.com/lanxin1020/archive/2009/05/09/269828.html#Feedback0http://m.tkk7.com/lanxin1020/comments/commentRss/269828.htmlhttp://m.tkk7.com/lanxin1020/services/trackbacks/269828.htmlstruts的validator的客戶端驗(yàn)證,不能進(jìn)行多表單頁面的驗(yàn)證,原因是由<html:script>標(biāo)簽生成的javascipt是根據(jù)每個(gè)表單,生成一段代碼。例如:

<html:javascript formName="searchSgbySjForm" dynamicJavascript="true" staticJavascript="false"/>
生成  :
             var bCancel = false; 
             function validateSearchSgbySjForm(form)
            {                                                                         
                if (bCancel)       return true;        
                else        return validateRequired(form) && validateDate(form);   
            }
            function required ()
           {     
               this.aa = new Array("sgfssjq", "事故發(fā)生時(shí)間起 不可為空.", new Function ("varName", "this.datePatternStrict='yyy-MM-dd'; return thisvarName];"));
               this.ab = new Array("sgfssjz", "事故發(fā)生時(shí)間止 不可為空.", new Function ("varName", "this.datePatternStrict='yyy-MM-dd';  return this[varName];"));   
           }

           function DateValidations ()
          {
              this.aa = new Array("sgfssjq", "事故發(fā)生時(shí)間起 不是有效的日期類型.", new Function ("varName", "this.datePatternStrict='yyy-MM-dd';  return this  [varName];"));
             this.ab = new Array("sgfssjz", "事故發(fā)生時(shí)間止 不是有效的日期類型.", new Function ("varName", "this.datePatternStrict='yyy-MM-dd';  return this[varName];"));   
         }

如果有多個(gè)的話required和DateValidations 都會(huì)重復(fù)的,而javascript是只認(rèn)最后一個(gè)函數(shù)的。所以,會(huì)導(dǎo)致驗(yàn)證出錯(cuò)。

再寫一個(gè)標(biāo)簽 ,主要根據(jù)原來的代碼修改,代碼如下:

package com.tmri.acd.tag;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.apache.commons.validator.Field;
import org.apache.commons.validator.Form;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.ValidatorResources;
import org.apache.commons.validator.util.ValidatorUtils;
import org.apache.commons.validator.Var;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.config.ModuleConfig;
import com.tmri.acd.tag.TagUtils;
import org.apache.struts.util.MessageResources;
import org.apache.struts.validator.Resources;
import org.apache.struts.validator.ValidatorPlugIn;
import java.util.StringTokenizer;

public class JavascriptValidatorTag extends BodyTagSupport
{
 private static final Comparator actionComparator = new Comparator()
{       
            public int compare(Object o1, Object o2)
           {
                 ValidatorAction va1 = (ValidatorAction) o1;           
                 ValidatorAction va2 = (ValidatorAction) o2;
                 if ((va1.getDepends() == null || va1.getDepends().length() == 0) && (va2.getDepends() == null || va2.getDepends().length() == 0))
                {               
                    return 0;
                }
                else if (  (va1.getDepends() != null && va1.getDepends().length() > 0)  && (va2.getDepends() == null || va2.getDepends().length() == 0))
               {  
                   return 1;
               }
}

 



lanxin1020 2009-05-09 22:59 發(fā)表評論
]]>
Strust組件—Action類詳解 (轉(zhuǎn))http://m.tkk7.com/lanxin1020/archive/2009/04/05/263973.htmllanxin1020lanxin1020Sun, 05 Apr 2009 03:19:00 GMThttp://m.tkk7.com/lanxin1020/archive/2009/04/05/263973.htmlhttp://m.tkk7.com/lanxin1020/comments/263973.htmlhttp://m.tkk7.com/lanxin1020/archive/2009/04/05/263973.html#Feedback0http://m.tkk7.com/lanxin1020/comments/commentRss/263973.htmlhttp://m.tkk7.com/lanxin1020/services/trackbacks/263973.htmlAction類是用戶請求和業(yè)務(wù)邏輯之間的橋梁,每個(gè)Action充當(dāng)客戶的一項(xiàng)業(yè)務(wù)代理。在RequestProcessor類預(yù)處理請求時(shí),在創(chuàng)建了Action的實(shí)例后,就調(diào)用自身的processActionPerform()方法,該方法再調(diào)用Action類的execute()。
Action的excute()方法調(diào)用模型的業(yè)務(wù)方法,完成用戶請求,然后根據(jù)執(zhí)行結(jié)果把請求轉(zhuǎn)發(fā)給其他合適的WEB組件。

一、Action類緩存

      struts應(yīng)用的生命周期中RequestProcessor只保證一個(gè)Action實(shí)例,所有的客戶請求都共享這個(gè)實(shí)例.所有請求可以同時(shí)執(zhí)行它的excute()方法。RequestProcessor類包含一個(gè)HashMap,作為存放所有Action實(shí)例的緩存。每個(gè)Action實(shí)例在緩存中存放的key為Action類名。在RequestProcessor類的processActionCreate()方法中,首先檢查在HashMap中是否存在Action實(shí)例,如果有直接使用,否則創(chuàng)建一個(gè)新的。創(chuàng)建Action實(shí)力的代碼位于同步代碼塊中,以保證只有一個(gè)線程創(chuàng)建Action實(shí)例,然后放在HashMap中。供其他線程使用。
如下代碼
  • protected Action processActionCreate(HttpServletRequest request,   
  •                                        HttpServletResponse response,   
  •                                        ActionMapping mapping)   
  •       throws IOException 
  • {   
  •       // Acquire the Action instance we will be using (if there is one)   
  •       String className = mapping.getType();   
  •       if (log.isDebugEnabled()) 
  •      {   
  •           log.debug(" Looking for Action instance for class " + className);   
  •       }   
  •   
  •       // :TODO: If there were a mapping property indicating whether   
  •       // an Action were a singleton or not ([true]),   
  •       // could we just instantiate and return a new instance here?   
  •   
  •       Action instance = null;   
  •       synchronized (actions) 
  •      {   
  •           // Return any existing Action instance of this class   
  •           instance = (Action) actions.get(className);   
  •           if (instance != null)
  •          {   
  •               if (log.isTraceEnabled()) 
  •              {   
  •                   log.trace("  Returning existing Action instance");   
  •               }   
  •               return (instance);   
  •           }   
  •   
  •           // Create and return a new Action instance   
  •           if (log.isTraceEnabled()) 
  •          {   
  •               log.trace("  Creating new Action instance");   
  •           }   
  •              
  •           try
  •          {   
  •               instance = (Action) RequestUtils.applicationInstance(className);   
  •               // :TODO: 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);   
  •           }         
  •           instance.setServlet(this.servlet);   
  •           actions.put(className, instance);   
  •       }   
  •   
  •       return (instance);   
  •   
  •   }  

     

    二.創(chuàng)建支持多線程的Action
    1.什么是線程安全的代碼
    在多線程環(huán)境下能正確執(zhí)行的代碼就是線程安全的。
    安全的意思是能正確執(zhí)行,否則后果是程序執(zhí)行錯(cuò)誤,可能出現(xiàn)各種異常情況。

    2.如何編寫線程安全的代碼
    很多書籍里都詳細(xì)講解了如何這方面的問題,他們主要講解的是如何同步線程對共享資源的使用的問題。主要是對synchronized關(guān)鍵字的各種用法,以及鎖的概念。
    Java1.5中也提供了如讀寫鎖這類的工具類。這些都需要較高的技巧,而且相對難于調(diào)試。

    但是,線程同步是不得以的方法,是比較復(fù)雜的,而且會(huì)帶來性能的損失。等效的代碼中,不需要同步在編寫容易度和性能上會(huì)更好些。
    我這里強(qiáng)調(diào)的是什么代碼是始終為線程安全的、是不需要同步的。如下:
    1)常量始終是線程安全的,因?yàn)橹淮嬖谧x操作。
    2)對構(gòu)造器的訪問(new 操作)是線程安全的,因?yàn)槊看味夹陆ㄒ粋€(gè)實(shí)例,不會(huì)訪問共享的資源。
    3)最重要的是:局部變量是線程安全的。因?yàn)槊繄?zhí)行一個(gè)方法,都會(huì)在獨(dú)立的空間創(chuàng)建局部變量,它不是共享的資源。局部變量包括方法的參數(shù)變量。

    Servlet是在多線程環(huán)境下的。即可能有多個(gè)請求發(fā)給一個(gè)servelt實(shí)例,每個(gè)請求是一個(gè)線程。 struts下的action也類似,同樣在多線程環(huán)境下,你也必須編寫線程安全的Action類。
    保證線程安全的原則就是僅僅使用局部變量,謹(jǐn)慎使用實(shí)例變量(擁有狀態(tài)的實(shí)例,尤其是擁有業(yè)務(wù)對象狀態(tài)的實(shí)例). 如果要用到那些有狀態(tài)的實(shí)例,唯一和最好的辦法是在Action類中,僅僅在Action類的execute()方法中使用局部變量,對于每個(gè)調(diào)用execute()方法的線程,JVM會(huì)在每個(gè)線程的堆棧中創(chuàng)建局部變量,因此每個(gè)線程擁有獨(dú)立的局部變量,不會(huì)被其他線程共享.當(dāng)線程執(zhí)行完execute()方法后,它的局部變量就會(huì)被銷毀.
    如果Action類的實(shí)例變量是必須的話,需要采用JAVA同步機(jī)制(synchronized)對訪問共享資源的代碼塊進(jìn)行同步


    三、Struts的幾種Action
    Struts提供了一些現(xiàn)成的Action類,直接使用可以大大節(jié)省時(shí)間,如下
    ForwardAction
    可以轉(zhuǎn)發(fā)到其他web組件,僅僅提供一個(gè)轉(zhuǎn)發(fā)功能,不作處理。
    IncludeAction
    包含其他web組件。
    DiapatchAction
    通常一個(gè)Action只完成一個(gè)操作,用這個(gè)Action可以完成一組相關(guān)的操作。
    LookupDispatchAction
    他是DiapatchAction的子類,也可以定義多個(gè)方法,但主要用于一個(gè)表單里有多個(gè)按鈕,而這些按鈕又有一個(gè)共同的名字的場合。
    SwitchAction
    用于子模塊之間的切換。


    四.ActionForward類
    Action類的excute()方法返回一個(gè)ActionForward對象,它代表了web資源的邏輯抽象,這里的web資源可以是jsp頁面、Java servlet、或Action。
    從excute返回ActionForward可以有兩種方法。
    1) 動(dòng)態(tài)創(chuàng)建一個(gè)ActionForward實(shí)例
    return new ActionForward(”Failure”,”login.jsp”,true);
    2) 調(diào)用ActionMappin實(shí)例的findForward方法
    這個(gè)方法先從action級(jí)別找,然后在<global-forwards />級(jí)別找
    return mapping.findForward(“Failure”);



  • lanxin1020 2009-04-05 11:19 發(fā)表評論
    ]]>
    Strust組件—RequestProcessor類詳解 (轉(zhuǎn))http://m.tkk7.com/lanxin1020/archive/2009/04/05/263970.htmllanxin1020lanxin1020Sun, 05 Apr 2009 03:15:00 GMThttp://m.tkk7.com/lanxin1020/archive/2009/04/05/263970.htmlhttp://m.tkk7.com/lanxin1020/comments/263970.htmlhttp://m.tkk7.com/lanxin1020/archive/2009/04/05/263970.html#Feedback0http://m.tkk7.com/lanxin1020/comments/commentRss/263970.htmlhttp://m.tkk7.com/lanxin1020/services/trackbacks/263970.htmlRequestProcessor類,每個(gè)子應(yīng)用模塊都可以有單獨(dú)的RequestProcessor類,

    ActionServlet主要負(fù)責(zé)初始化,以及介紹請求并找到合適的RequestRrocessor,之后真正干活的是RequestProecssor和Action.
    上回說到ActionServlet的process方法最終會(huì)調(diào)用RequestProcessor類的process方法.下面介紹這個(gè)方法.
    一.RequestProcessor的process方法
    public void process(HttpServletRequest request,   
  •                         HttpServletResponse response)   
  •         throws IOException, ServletException 
  • {   
  •         // Wrap multipart requests with a special wrapper   
  •         request = processMultipart(request);   
  •         // Identify the path component we will use to select a mapping   
  •         String path = processPath(request, response);   
  •         if (path == null
  •        {   
  •             return;   
  •         }    
  •         if (log.isDebugEnabled()) 
  •        {   
  •             log.debug("Processing a '" + request.getMethod() +   
  •                       "' for path '" + path + "'");   
  •         }   
  •         // Select a Locale for the current user if requested   
  •         processLocale(request, response);   
  •         // Set the content type and no-caching headers if requested   
  •         processContent(request, response);   
  •         processNoCache(request, response);   
  •         // General purpose preprocessing hook   
  •         if (!processPreprocess(request, response)) 
  •         {   
  •             return;   
  •         }   
  •         this.processCachedMessages(request, response);   
  •         // Identify the mapping for this request   
  •         ActionMapping mapping = processMapping(request, response, path);   
  •         if (mapping == null)
  •        {   
  •             return;   
  •         }   
  •         // Check for any role required to perform this action   
  •         if (!processRoles(request, response, mapping)) 
  •        {   
  •             return;   
  •         }   
  •         // Process any ActionForm bean related to this request   
  •         ActionForm form = processActionForm(request, response, mapping);   
  •         processPopulate(request, response, form, mapping);   
  •         // 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;   
  •         }   
  •                
  •         // Process a forward or include specified by this mapping   
  •         if (!processForward(request, response, mapping))
  •        {   
  •             return;   
  •         }   
  •         if (!processInclude(request, response, mapping)) 
  •        {   
  •             return;   
  •         }   
  •         // Create or acquire the Action instance to process this request   
  •         Action action = processActionCreate(request, response, mapping);   
  •         if (action == null)
  •         {   
  •             return;   
  •         }   
  •         // Call the Action instance itself   
  •         ActionForward forward =   
  •             processActionPerform(request, response,   
  •                                  action, form, mapping);   
  •   
  •         // Process the returned ActionForward instance   
  •         processForwardConfig(request, response, forward);   
  •   
  •     }   

    1) 調(diào)用processMultipart()方法
    如果HTTP請求方式為post,并且contentType為”multipart/form-data”開頭,標(biāo)準(zhǔn)的HttpServletRequest對象將被重新包裝,以方便處理”multipart”類型的HTTP請求.如果請求方式為get,或正congtentType屬性不是”mulitipart”,就直接返回原始的HttpServletRequest對象.

    2) 調(diào)用processPath()方法
    獲得請求的URI的路徑,這一信息可用于選擇合適的Struts Action組件.

    3) 調(diào)用processLocale方法
    當(dāng)ControllerConfig對象的locale屬性為true,將讀取用戶請求中包含的Locale信息,然后把Locale實(shí)例保存在session范圍內(nèi).

    4) 調(diào)用processContendType(contentType)方法
    讀取ControllerConfig對象的conttentType屬性,然后調(diào)用response.setContentType(contentType)方法,設(shè)置響應(yīng)結(jié)果的文檔類型和字符編碼.
    processContent()方法如下

  • protected void processContent(HttpServletRequest request,   
  •                                  HttpServletResponse response) 
  •  {   
  •   
  •        String contentType = moduleConfig.getControllerConfig().getContentType();   
  •        if (contentType != null
  •       {   
  •            response.setContentType(contentType);   
  •        }   
  •   
  •    }   

     


    5) 調(diào)用processNoCache()方法
    讀取ControllerConfig對象的nocache屬性,如果nocache屬性為true,在響應(yīng)結(jié)果中將加入特定的頭參數(shù):Pragma,Cache-Control和Expires,
    防止頁面被存儲(chǔ)在客戶的瀏覽器的緩存中,processNoCache方法的代碼如下:

  • protected void processNoCache(HttpServletRequest request,   
  •                                   HttpServletResponse response) 
  • {   
  •   
  •         if (moduleConfig.getControllerConfig().getNocache()) 
  •         {   
  •             response.setHeader("Pragma""No-cache");   
  •             response.setHeader("Cache-Control""no-cache,no-store,max-age=0");   
  •             response.setDateHeader("Expires"1);   
  •         }   
  •     }  



    6)調(diào)用processPreprocess()方法
    該方法不執(zhí)行任何操作.直接返回true.子類可以覆蓋這個(gè)方法.
    執(zhí)行客戶化的預(yù)處理請求操作.

    7)調(diào)用processMapping()方法
    尋找和用戶請求的URI匹配的ActionMapping,如果不存在這樣的ActionMapping,則向用戶返回恰當(dāng)?shù)腻e(cuò)誤信息.

    8)調(diào)用processRoles()方法
    先判斷是否為Action配置了安全角色,如果配置了安全角色,就調(diào)用isUserInRole()方法判斷當(dāng)前用戶是否具備必需的角色,如果不具備,就結(jié)束請求處理流程.,向用戶返回恰當(dāng)?shù)腻e(cuò)誤消息.

    9)調(diào)用processActionForm()方法
    先判斷是否為ActionMapping配置了ActionForm,如果配置了ActionForm,就先從ActionForm的存在范圍內(nèi)(request或session)尋找改ActionForm實(shí)例,如果不存在,就創(chuàng)建一個(gè)實(shí)例,接下來把它保存在合適的范圍內(nèi),保存時(shí)使用的屬性key為ActionMapping的name屬性。

    10)調(diào)用processPopulate()方法
    如果為ActionMapping配置了ActionForm,就先調(diào)用ActionForm的reset()方法,再把請求中的表單數(shù)據(jù)組裝到ActionForm中。

    11)調(diào)用processValidate()方法
    如果為ActionMapping配置了ActionForm,并且ActionMapping的validate屬性為true,就調(diào)用ActionForm的validate()方法,如果validate方法返回的ActionErrors對象中包含ActionMessage對象,說明表單驗(yàn)證失敗。就把ActionErrors對象放在request范圍內(nèi),再把請求轉(zhuǎn)發(fā)到ActionMapping的input屬性指定的Web組件。如果ActionForm的validate方法執(zhí)行表單驗(yàn)證成功,就繼續(xù)執(zhí)行下面的處理流程。

    12)調(diào)用processForward()方法
    判斷是否在ActionMapping中配置了forward屬性。如果配置了這個(gè)屬性,就調(diào)用RequestDispatcher的forward方法,請求處理流程結(jié)束。否則進(jìn)行下一步。

    13)調(diào)用processInclude()方法
    判斷是否在ActionMapping中配置了include屬性。如果配置了這個(gè)屬性,就調(diào)用RequestDispatcher的include方法,請求處理流程結(jié)束。否則進(jìn)行下一步。

    14)調(diào)用processActionCreate()方法
    先判斷是否在Action緩存中存在這個(gè)Action實(shí)例,如果沒有就新建一個(gè)Action實(shí)例,把它放在Action緩存中。可以看出Action也是只有一個(gè)實(shí)例在運(yùn)行的。

    15)調(diào)用processActionPerform
    該方法調(diào)用Action實(shí)例的execute方法,該方法位于try/catch中,以及捕獲異常。processActionPerform()方放代碼如下。

  • 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));   
  •        }   
  •    

     


    16)調(diào)用processActionForward方法
    把你的Action的excute方法返回的ActionFoward對象作為參數(shù)傳給它,processActionForward對象包的請求轉(zhuǎn)發(fā)信息來執(zhí)行請求轉(zhuǎn)發(fā)或重定向。

    RequestProcessor類的process方法中,會(huì)訪問ControllerConfig、ActionMappig和ActionForward實(shí)力的屬性,ControllerConfig類和struts配置文件的<controlle>r元素對應(yīng),ActionMapping類和<action>元素對應(yīng),ActionForward和<forward>元素對應(yīng),process方法通過訪問這三個(gè)類實(shí)例的屬性來獲得相關(guān)的配置信息。
    寫了這么多,RequestProcessor干得事夠多的吧。

    二.?dāng)U展RequestProcessor
    如果想修改RequestProcessor的一些默認(rèn)功能,改易覆蓋RequestProcessor基類中的相關(guān)方法.

  • Public class CustomRequestProcessor extends RequestProcessor{   
  •   protected void processPreprocess (HttpServletRequest request,   
  •                                  HttpServletResponse response) {    
  • ………………….   
  • }   
  • }  

    在struts配置文件中,<controller>元素的processorClass屬性用于配置你自己的RequestProcessor

  • </controller    
  • contentType=“text/html:charset=”GB2312”   
  • locale=”true” nocache=”true” processorCalss=”com.test.CustomRequestProcessor”/>  

     




     



  • lanxin1020 2009-04-05 11:15 發(fā)表評論
    ]]>
    Strust組件—ActionServlet詳解(轉(zhuǎn))http://m.tkk7.com/lanxin1020/archive/2009/04/05/263969.htmllanxin1020lanxin1020Sun, 05 Apr 2009 03:10:00 GMThttp://m.tkk7.com/lanxin1020/archive/2009/04/05/263969.htmlhttp://m.tkk7.com/lanxin1020/comments/263969.htmlhttp://m.tkk7.com/lanxin1020/archive/2009/04/05/263969.html#Feedback0http://m.tkk7.com/lanxin1020/comments/commentRss/263969.htmlhttp://m.tkk7.com/lanxin1020/services/trackbacks/263969.html 控制器將模型層和視圖層分開,這樣分離,可以為同一個(gè)模型開發(fā)出不同的視圖.
            下面時(shí)Struts的三大主要組件
    ActionServlet組件:充當(dāng)Struts框架的中央控制器
    RequestProcessor組件:充當(dāng)每個(gè)子應(yīng)用模塊的請求處理器
    Action組件:真正來處理一項(xiàng)具體的業(yè)務(wù).

    一. Struts的init()方法
    Struts應(yīng)用中只存在ActionServlet的一個(gè)實(shí)例,Servlet容器在啟動(dòng)時(shí),或者用戶首次請求ActionServlet時(shí)加載ActionServlet類.在這兩種情況下,servlet容器都會(huì)在ActionServlet容器被加載后立即執(zhí)行它的init()方法,這可以保證ActionServlet處理用戶請求時(shí)已經(jīng)被初始化.

    下面根據(jù)Init()講述Struts的初始化過程
  • public void init() throws ServletException {   
  •   
  •         // Wraps the entire initialization in a try/catch to better handle   
  •         // unexpected exceptions and errors to provide better feedback   
  •         // to the developer   
  •         try {   
  • //調(diào)用initInternal()方法,初始化Struts框架內(nèi)的消息資源,如與系統(tǒng)日志相關(guān)的通知,警告,和錯(cuò)誤消息.   
  • 1)initInternal();   
  •   
  • //調(diào)用ininOther()方法,從web.xml文件中加載ActionServlet的初始化參數(shù),如config參數(shù)   
  • 2)initOther();   
  •   
  • //調(diào)用initServlet()方法,從web.xml文件中加載ActionServlet的URL映射信息.同時(shí)還會(huì)注冊web.xml文件和Struts配置文件所使用的DTD文件,這些DTD文件用戶驗(yàn)證web.xml和struts配置文件的語法.其中方法里的 digester類負(fù)責(zé)解析web.xml,對字符串servletMapping屬性進(jìn)行初始化   
  • 3) initServlet();   
  •   
  • //把ActionServlet實(shí)例放到ServletContext里   
  • getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);   
  •   
  • //初始化一個(gè)factory,用于創(chuàng)建moduleConfig   
  • initModuleConfigFactory();   
  •   
  • //,加載并解析默認(rèn)struts配置文件/WEB-INF/struts-config.xml,同時(shí)創(chuàng)建MoudleConfig實(shí)例,放到ServletContext中   
  • 4)ModuleConfig moduleConfig = initModuleConfig("", config);   
  •   
  • //加載并初始化默認(rèn)子應(yīng)用模塊的消息資源;講解MessageResources對象,把它存儲(chǔ)在ServletContext中.   
  • 5)initModuleMessageResources(moduleConfig);   
  •   
  • //加載并初始化默認(rèn)子應(yīng)用模塊的數(shù)據(jù)源,如果在struts配置文件中沒有定義<data-sources >元素,忽略這一流程.   
  • 6)initModuleDataSources(moduleConfig);   
  •   
  • //加載并初始化默認(rèn)子應(yīng)用的所有插件   
  • 7)initModulePlugIns(moduleConfig);   
  •   
  • //凍結(jié)moduleConfig(,在方法返回之前不能修改它,否則將拋出異常)   
  • moduleConfig.freeze();   
  •            
  • //如果還有其他子應(yīng)用模塊,將重復(fù)4-7步   
  •       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();   
  •      }   
  •   
  • //將各個(gè)子模塊應(yīng)用(除了默認(rèn)的)的前綴存到一個(gè)字符數(shù)組中,并放到servletcontext中   
  • this.initModulePrefixes(this.getServletContext());   
  • //釋放創(chuàng)建的用于讀取配置文件的digester實(shí)例,釋放內(nèi)存   
  •             this.destroyConfigDigester();   
  •         } 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   
  •             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());   
  •         }       
  • }  
  •        將各個(gè)子模塊應(yīng)用(除了默認(rèn)的)的前綴存到一個(gè)字符數(shù)組中,并放到servletcontext中,對于默認(rèn)的子應(yīng)用模塊,在appclication范圍內(nèi)存放他的MoudleConfig實(shí)例的key為“org.apache.struts.action.MODULE”,其他模塊如/account,存放的key為org.apache.struts.action.MODULE/account,消息,數(shù)據(jù)源和插件等部分存在servletcontext的key和上述方法類似,不在說明.


    二.ActionServlet的process方法
    當(dāng)ActionServlet接受到HTTP請求后,在doget()或doPost()方法中都會(huì)調(diào)用process()方法來處理請求.

  •  public void doGet(HttpServletRequest request,   
  •               HttpServletResponse response)   
  •         throws IOException, ServletException {   
  •   
  •         process(request, response);   
  •   
  • }   

  •   public void doPost(HttpServletRequest request,   

  •                HttpServletResponse response)   
  •         throws IOException, ServletException {   
  •   
  •         process(request, response);   
  •   
  • }   
  • 下面是process方法,它看上去并不復(fù)雜,但他調(diào)用的其他方法比較復(fù)雜. 
     protected void process(HttpServletRequest request, HttpServletResponse response)   

  •         throws IOException, ServletException {   
  •         //根據(jù)request里的信息從servletContext里找到相應(yīng)的子模塊ModuleConfig,和它下面的MessageResources,并放到request里,使其他組件可以方便的供request里取得應(yīng)用配置信息和消息資源.   
  •         ModuleUtils.getInstance().selectModule(request, getServletContext());   
  • //取出MoudleConfig實(shí)例config   
  •         ModuleConfig config = getModuleConfig(request);   
  •     //根據(jù)config里這個(gè)子模塊的信息,從servletcontext里,取出這個(gè)子模塊的RequestProcessor實(shí)例   
  •         RequestProcessor processor = getProcessorForModule(config);   
  •     //如果processor實(shí)例為空,就新建一個(gè).同時(shí)放到servletcontext里.   
  •         if (processor == null) {   
  •            processor = getRequestProcessor(config);   
  •         }   
  • //調(diào)用RequestProcessor的process方法處理,   
  •         processor.process(request, response);   
  •     }  

  • 三. 擴(kuò)展ActionServlet
    從Struts1.1開始,為減輕ActionServlet的負(fù)擔(dān),多數(shù)功能已經(jīng)移到RequestProcessor類中,所以基本不用擴(kuò)展ActionServlet

    如果需要?jiǎng)?chuàng)建自己的ActionServlet,則可以創(chuàng)建一個(gè)它的子類.覆蓋init()方法(或其他方法),可以寫一些自己的操作,但要先調(diào)用super.init();
    定義如下的類:

  • package sample;    
  • public class ExtendedActionServlet extends ActionServlet {    
  •         public void init() throws ServletException {    
  •                super.init();    
  •                //do some operations    
  •                ……………    
  •         }    
  • }   


  • 擴(kuò)展完類后,還應(yīng)該在web.xml文件中如下配置:

  • <servlet>    
  •         <servlet-name>sample</servlet-name>    
  •         <servlet-class>sample.ExtendedActionServlet</servlet-class>    
  • </servlet>    
  •     
  • <servlet-mapping>    
  •        <servlet-name>sample</servlet-name>    
  •        <url-pattern>/action/*<url-pattern> 



  • 上面的/action/*表示負(fù)責(zé)處理所有以/action為前綴的URL,后面的/表示轉(zhuǎn)義


    lanxin1020 2009-04-05 11:10 發(fā)表評論
    ]]>
    主站蜘蛛池模板: 永久黄网站色视频免费观看| 国产亚洲精品成人AA片| 国产一级高清免费观看| 91免费人成网站在线观看18| 日韩毛片免费一二三| 97se亚洲国产综合自在线| 亚洲国产精品久久66| 亚洲中文字幕在线第六区| www亚洲精品少妇裸乳一区二区| 免费看污成人午夜网站| 99热这里有免费国产精品| 中文字幕免费在线观看动作大片| 亚洲Av永久无码精品黑人| 精品久久久久久亚洲精品| 久久亚洲一区二区| 亚洲人成人77777网站| 亚洲国产综合久久天堂| 国产婷婷高清在线观看免费| 成人无遮挡裸免费视频在线观看 | 日韩精品无码免费专区网站 | 亚洲国产成人久久一区WWW| 国产成人aaa在线视频免费观看| 青青青国产在线观看免费 | 亚洲精品偷拍无码不卡av| 久久国产亚洲观看| 亚洲av无码一区二区三区网站| 最新国产AV无码专区亚洲| 亚洲成?v人片天堂网无码| 免费一级特黄特色大片在线| 日本黄色免费观看| 国产高清在线精品免费软件| 成人免费无遮挡无码黄漫视频| 日韩一区二区a片免费观看 | 久热综合在线亚洲精品| 亚洲av永久无码精品表情包| 亚洲精品无码不卡在线播HE | 国产精品免费观看视频| 特级毛片免费播放| 猫咪www免费人成网站| 九九免费久久这里有精品23| 一级午夜免费视频|