搜尋
首頁Javajava教程Struts1之ActionMapping實例講解

Struts1之ActionMapping實例講解

Sep 06, 2017 am 09:34 AM
講解

這篇文章主要介紹了Struts1教學之ActionMapping,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧

首先斷點走出了processpath方法,

#  

這個方法是用來截取字串的,今天我們來看看怎麼獲得ActionMapping的方法---processMapping。

在此之前簡單說一下ActionMapping,它的原始程式碼中可以看出,其中最重要的屬性和我們的mvc小實例中的ActionMapping類似,都是有path、type還有forwardMap,主要是對應的struts-config設定檔而來,這個就是保存這個設定檔的資訊到記憶體中。

具體的mvc小實例的ActionMapping程式碼如下:


package com.cjq.servlet; 
import java.util.Map; 
public class ActionMapping { 
  private String path; 
  private Object type; 
  private Map forwardMap; 
  public String getPath() { 
    return path; 
  } 
  public void setPath(String path) { 
    this.path = path; 
  }  
  public Object getType() { 
    return type; 
  } 
 
  public void setType(Object type) { 
    this.type = type; 
  } 
 
  public Map getForwardMap() { 
    return forwardMap; 
  } 
 
  public void setForwardMap(Map forwardMap) { 
    this.forwardMap = forwardMap; 
  } 
}

而Struts中的Actionconfig(因為ActionMapping是繼承這個ActionConfig的,所以我們來看ActionConfig比較直接)的程式碼如下:

從這兩部分程式碼來看,更印證了我在開篇寫的mvc小實例是一個struts框架的雛形。

講完ActionMapping的一些內容後,相信對ActionMapping有所了解,那麼系統是如何產生ActionMapping和如何找到ActionMapping的呢?這就是今天要說的整體:

我們看下web.xml中有一個2  設定訊息,這個訊息就是說明了但伺服器已啟動就動態讀取struts-config設定檔把設定檔的資訊put到ActionMapping。所以當我們運行伺服器的時候,我們在記憶體中已經存在對應struts-config設定檔資訊對應的ActionMapping。今天就是要透過processMapping讀取這個ActionMapping類別。

進入斷點偵錯,先在processMapping方法上設定斷點。

    

進入原始程式碼中:


/** 
   * <p>Select the mapping used to process theselection path for this request 
   * If no mapping can be identified, createan error response and return 
   * <code>null</code>.</p> 
   * 
   * @param request The servlet request weare processing 
   * @param response The servlet response weare creating 
   * @param path The portion of the requestURI for selecting a mapping 
   * 
   * @exception IOException if an input/outputerror occurs 
   */ 
  protectedActionMapping processMapping(HttpServletRequestrequest, 
                     HttpServletResponse response, 
                     String path) 
    throws IOException { 
  
    // Is there a mapping for this path? 
    ActionMapping mapping = (ActionMapping) 
      moduleConfig.findActionConfig(path); 
  
    // If a mapping is found, put it in the request and return it 
    if (mapping != null) { 
      request.setAttribute(Globals.MAPPING_KEY, mapping); 
      return (mapping); 
    } 
  
    // 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); 
      } 
    } 
  
    // 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; 
  }

首先我們傳入我們在上一步所截取的路徑,透過moduleConfig的findAction方法來找出ActionConfig,並且傳回ActionMapping。具體程式碼是:


ActionMapping mapping =(ActionMapping) 
   moduleConfig.findActionConfig(path);

如果找到,那就講ActionMapping存放到request的context中。程式碼:


if (mapping != null) { 
      request.setAttribute(Globals.MAPPING_KEY, mapping); 
      return (mapping); 
    }

如果沒有透過path找到mapping,則在Actionconfig中遍歷為未知路徑尋找mapping,如果找到則存放到request中,如果沒有找到,則回傳錯誤訊息,具體程式碼如下:


// Locate the mapping for unknownpaths (if any) 
    ActionConfig configs[] = moduleConfigfindActionConfigs(); 
    for (int i = 0; i < configslength; i++) { 
      if (configs[i].getUnknown()) { 
        mapping = (ActionMapping)configs[i]; 
        request.setAttribute(Globals.MAPPING_KEY, mapping); 
        return (mapping); 
      } 
    } 
  
    // 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;

來看下ActionServlet中的一個方法processActionForm,當我們在截取字串,再根據字串在取得ActionMapping(這是前兩篇文章中介紹的)之後,我們就要用利用ActionMapping來建立ActionForm了,並且把ActionForm放到request或session中管理。

先來看看特定struts中processActionForm方法的具體實作:


/** 
   * <p>Retrieve and return the <code>ActionForm</code> associatedwith 
   * this mapping, creating and retaining oneif necessary. If there is no 
   * <code>ActionForm</code> associated with this mapping,return 
   * <code>null</code>.</p> 
   * 
   * @param request The servlet request weare processing 
   * @param response The servlet response weare creating 
   * @param mapping The mapping we are using 
   */ 
  protectedActionForm processActionForm(HttpServletRequestrequest, 
                     HttpServletResponse response, 
                     ActionMapping mapping) { 
    // Create (if necessary) a form bean to use 
    ActionForm instance = RequestUtilscreateActionForm 
      (request, mapping, moduleConfig, servlet); 
    if (instance == null) { 
      return (null); 
    } 
 
      // Store the new instance in the appropriate scope 
    if (log.isDebugEnabled()) { 
      log.debug(" Storing ActionForm bean instance in scope &#39;" + 
       mapping.getScope() + "&#39; under attribute key &#39;" + 
       mapping.getAttribute() + "&#39;"); 
    } 
    if ("request".equals(mapping.getScope())) { 
      request.setAttribute(mapping.getAttribute(), instance); 
 
    } else { 
 
      HttpSession session =requestgetSession(); 
 
      session.setAttribute(mapping.getAttribute(), instance); 
 
    } 
 
    return (instance); 
 
  
 
}

這個方法的大體流程是:根據ActionMapping中的name名稱查找ActionForm,如果配置了ActionForm,那麼就到request或session中查找,如果在request或session中存在已經建立的ActionForm,那麼將會回傳。如果不存在那麼會根據ActionForm的完成路徑採用反射進行創建,再將創建好的ActionForm放到request或session中,之後再傳回ActionForm。

#具體我們可以跟隨斷點偵錯來看看這個方法是如何運作的。

先設定斷點,之後再進入processActionForm方法。

第一個步驟就是建立ActionForm:


// Create (if necessary) a formbean to use 
 
    ActionForm instance = RequestUtils.createActionForm 
 
      (request, mapping, moduleConfig, servlet); 
 
    if (instance == null) { 
 
      return (null); 
 
    }

透過呼叫RequestUtils.createActionForm的方法把ActionMapping中的ActionForm字串產生對象,並且返回。進入這段程式碼:


publicstaticActionForm createActionForm( 
 
      HttpServletRequest request, 
 
      ActionMapping mapping, 
 
      ModuleConfig moduleConfig, 
 
      ActionServlet servlet) { 
 
  
 
    // Is there a form bean associated with this mapping? 
 
    String attribute = mappinggetAttribute(); 
 
    if (attribute == null) { 
 
      return (null); 
 
    } 
 
  
 
    // Look up the form bean configuration information to use 
 
    String name = mapping.getName(); 
 
    FormBeanConfig config =moduleConfigfindFormBeanConfig(name); 
 
    if (config == null) { 
 
      log.warn("No FormBeanConfig found under &#39;"+ name + "&#39;"); 
 
      return (null); 
 
    } 
 
  
 
    ActionForm instance = lookupActionForm(request,attribute, mappinggetScope()); 
 
  
 
    // Can we recycle the existing form bean instance (if there is one)? 
 
    try { 
 
      if (instance != null && canReuseActionForm(instance,config)) { 
 
        return (instance); 
 
      } 
 
    } catch(ClassNotFoundException e) { 
 
      log.error(servlet.getInternal().getMessage("formBean",config.getType()), e); 
 
      return (null); 
 
    } 
 
  
 
    return createActionForm(config,servlet); 
 
}

方法先定義變數name,並且從mapping取得值,String name = mapping.getName();也就是我們實例中的LoginForm字串。之後透過呼叫FormBeanConfig config =moduleConfig.findFormBeanConfig(name);這句話把對應的LoginForm字串產生對應的物件。

這裡要說明的是我們在struts-config設定檔中,配置過這樣一個標籤資訊:


<form-beans> 
 
    <form-bean name="loginForm" type=".struts.LoginActionForm"/> 
 
  </form-beans>

这个标签在服务器一启动的时候就会利用digester读取这里的配置信息,并且放在FormBeanConfig类中,这样我们可以通过上面那一句话就可以把LoginForm字符串生成相应的对象。

之后调用了ActionForm instance = lookupActionForm(request,attribute, mapping.getScope());这个方法,这个方法主要是查找scope属性中有没有存在ActionForm。具体实现:


if ("request".equals(scope)){ 
 
      instance = (ActionForm)request.getAttribute(attribute); 
 
    } else { 
 
      session = request.getSession(); 
 
      instance = (ActionForm)session.getAttribute(attribute); 
 
    }

这里判断scope属性值是否为request,如果是则从request中读出ActionForm,如果不是则从session中读出。程序如果是第一次执行,那么ActionForm会是为空的。因为这里的ActionForm为空,所以就进入了if判断语句中,最后通过调用return createActionForm(config, servlet);创建ActionForm并且返回。

之后processActionForm就会把返回来的ActionForm放入request或者session中。具体实现就是:


if ("request".equals(mapping.getScope())){ 
 
      request.setAttribute(mapping.getAttribute(), instance); 
 
    } else { 
 
      HttpSession session =request.getSession(); 
 
      session.setAttribute(mapping.getAttribute(), instance); 
 
    }

到此为止,ActionForm就创建完成,当ActionForm创建完成之后,就要用其他的方法来往ActionForm中赋值了

以上是Struts1之ActionMapping實例講解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JVM如何在不同平台上管理垃圾收集?JVM如何在不同平台上管理垃圾收集?Apr 28, 2025 am 12:23 AM

JVMmanagesgarbagecollectionacrossplatformseffectivelybyusingagenerationalapproachandadaptingtoOSandhardwaredifferences.ItemploysvariouscollectorslikeSerial,Parallel,CMS,andG1,eachsuitedfordifferentscenarios.Performancecanbetunedwithflagslike-XX:NewRa

為什麼Java代碼可以在不同的操作系統上運行,而無需修改?為什麼Java代碼可以在不同的操作系統上運行,而無需修改?Apr 28, 2025 am 12:14 AM

Java代碼可以在不同操作系統上無需修改即可運行,這是因為Java的“一次編寫,到處運行”哲學,由Java虛擬機(JVM)實現。 JVM作為編譯後的Java字節碼與操作系統之間的中介,將字節碼翻譯成特定機器指令,確保程序在任何安裝了JVM的平台上都能獨立運行。

描述編譯和執行Java程序的過程,突出平台獨立性。描述編譯和執行Java程序的過程,突出平台獨立性。Apr 28, 2025 am 12:08 AM

Java程序的編譯和執行通過字節碼和JVM實現平台獨立性。 1)編寫Java源碼並編譯成字節碼。 2)使用JVM在任何平台上執行字節碼,確保代碼的跨平台運行。

基礎硬件架構如何影響Java的性能?基礎硬件架構如何影響Java的性能?Apr 28, 2025 am 12:05 AM

Java性能与硬件架构密切相关,理解这种关系可以显著提升编程能力。1)JVM通过JIT编译将Java字节码转换为机器指令,受CPU架构影响。2)内存管理和垃圾回收受RAM和内存总线速度影响。3)缓存和分支预测优化Java代码执行。4)多线程和并行处理在多核系统上提升性能。

解釋為什麼本地庫可以破壞Java的平台獨立性。解釋為什麼本地庫可以破壞Java的平台獨立性。Apr 28, 2025 am 12:02 AM

使用原生庫會破壞Java的平台獨立性,因為這些庫需要為每個操作系統單獨編譯。 1)原生庫通過JNI與Java交互,提供Java無法直接實現的功能。 2)使用原生庫增加了項目複雜性,需要為不同平台管理庫文件。 3)雖然原生庫能提高性能,但應謹慎使用並進行跨平台測試。

JVM如何處理操作系統API的差異?JVM如何處理操作系統API的差異?Apr 27, 2025 am 12:18 AM

JVM通過JavaNativeInterface(JNI)和Java標準庫處理操作系統API差異:1.JNI允許Java代碼調用本地代碼,直接與操作系統API交互。 2.Java標準庫提供統一API,內部映射到不同操作系統API,確保代碼跨平台運行。

Java 9影響平台獨立性中引入的模塊化如何?Java 9影響平台獨立性中引入的模塊化如何?Apr 27, 2025 am 12:15 AM

modularitydoesnotdirectlyaffectJava'splatformindependence.Java'splatformindependenceismaintainedbytheJVM,butmodularityinfluencesapplicationstructureandmanagement,indirectlyimpactingplatformindependence.1)Deploymentanddistributionbecomemoreefficientwi

什麼是字節碼,它與Java的平台獨立性有何關係?什麼是字節碼,它與Java的平台獨立性有何關係?Apr 27, 2025 am 12:06 AM

BytecodeinJavaistheintermediaterepresentationthatenablesplatformindependence.1)Javacodeiscompiledintobytecodestoredin.classfiles.2)TheJVMinterpretsorcompilesthisbytecodeintomachinecodeatruntime,allowingthesamebytecodetorunonanydevicewithaJVM,thusfulf

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器