搜尋
首頁Javajava教程關於Struts1之ActionMapping的範例詳解

這篇文章主要介紹了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
是否有任何威脅或增強Java平台獨立性的新興技術?是否有任何威脅或增強Java平台獨立性的新興技術?Apr 24, 2025 am 12:11 AM

新興技術對Java的平台獨立性既有威脅也有增強。 1)雲計算和容器化技術如Docker增強了Java的平台獨立性,但需要優化以適應不同雲環境。 2)WebAssembly通過GraalVM編譯Java代碼,擴展了其平台獨立性,但需與其他語言競爭性能。

JVM的實現是什麼,它們都提供了相同的平台獨立性?JVM的實現是什麼,它們都提供了相同的平台獨立性?Apr 24, 2025 am 12:10 AM

不同JVM實現都能提供平台獨立性,但表現略有不同。 1.OracleHotSpot和OpenJDKJVM在平台獨立性上表現相似,但OpenJDK可能需額外配置。 2.IBMJ9JVM在特定操作系統上表現優化。 3.GraalVM支持多語言,需額外配置。 4.AzulZingJVM需特定平台調整。

平台獨立性如何降低發展成本和時間?平台獨立性如何降低發展成本和時間?Apr 24, 2025 am 12:08 AM

平台獨立性通過在多種操作系統上運行同一套代碼,降低開發成本和縮短開發時間。具體表現為:1.減少開發時間,只需維護一套代碼;2.降低維護成本,統一測試流程;3.快速迭代和團隊協作,簡化部署過程。

Java的平台獨立性如何促進代碼重用?Java的平台獨立性如何促進代碼重用?Apr 24, 2025 am 12:05 AM

Java'splatformindependencefacilitatescodereusebyallowingbytecodetorunonanyplatformwithaJVM.1)Developerscanwritecodeonceforconsistentbehavioracrossplatforms.2)Maintenanceisreducedascodedoesn'tneedrewriting.3)Librariesandframeworkscanbesharedacrossproj

您如何在Java應用程序中對平台特定問題進行故障排除?您如何在Java應用程序中對平台特定問題進行故障排除?Apr 24, 2025 am 12:04 AM

要解決Java應用程序中的平台特定問題,可以採取以下步驟:1.使用Java的System類查看系統屬性以了解運行環境。 2.利用File類或java.nio.file包處理文件路徑。 3.根據操作系統條件加載本地庫。 4.使用VisualVM或JProfiler優化跨平台性能。 5.通過Docker容器化確保測試環境與生產環境一致。 6.利用GitHubActions在多個平台上進行自動化測試。這些方法有助於有效地解決Java應用程序中的平台特定問題。

JVM中的類加載程序子系統如何促進平台獨立性?JVM中的類加載程序子系統如何促進平台獨立性?Apr 23, 2025 am 12:14 AM

類加載器通過統一的類文件格式、動態加載、雙親委派模型和平台無關的字節碼,確保Java程序在不同平台上的一致性和兼容性,實現平台獨立性。

Java編譯器會產生特定於平台的代碼嗎?解釋。Java編譯器會產生特定於平台的代碼嗎?解釋。Apr 23, 2025 am 12:09 AM

Java編譯器生成的代碼是平台無關的,但最終執行的代碼是平台特定的。 1.Java源代碼編譯成平台無關的字節碼。 2.JVM將字節碼轉換為特定平台的機器碼,確保跨平台運行但性能可能不同。

JVM如何處理不同操作系統的多線程?JVM如何處理不同操作系統的多線程?Apr 23, 2025 am 12:07 AM

多線程在現代編程中重要,因為它能提高程序的響應性和資源利用率,並處理複雜的並發任務。 JVM通過線程映射、調度機制和同步鎖機制,在不同操作系統上確保多線程的一致性和高效性。

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

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

熱工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。