search
HomeJavajavaTutorialStruts1 ActionMapping example explanation

This article mainly introduces the ActionMapping of the Struts1 tutorial. The editor thinks it is quite good. Now I will share it with you and give it as a reference. Let’s follow the editor and take a look.

First of all, the breakpoint is out of the processpath method.

This method is used To intercept strings, today we will look at how to obtain the ActionMapping method---processMapping.

Before that, let’s briefly talk about ActionMapping. It can be seen from its source code that the most important attributes are similar to the ActionMapping in our mvc small instance. They all have path, type and forwardMap. The main ones are It comes from the corresponding struts-config configuration file. This is to save the information of this configuration file into memory.

The ActionMapping code of the specific mvc small instance is as follows:


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

And the Actionconfig in Struts (because ActionMapping inherits this ActionConfig, so let’s take a look ActionConfig is more direct) The code is as follows:

##From these two parts of code Look, it further proves that the small mvc example I wrote at the beginning is the prototype of a struts framework.

After talking about some contents of ActionMapping, I believe that I have some understanding of ActionMapping. So how does the system generate ActionMapping and how to find ActionMapping? This is the whole thing I want to talk about today:

Let’s take a look at the configuration information of 2 in web. Once started, the struts-config configuration file is dynamically read and the information in the configuration file is put into ActionMapping. So when we run the server, we already have the ActionMapping corresponding to the struts-config configuration file information in the memory. Today we are going to read this ActionMapping class through processMapping.


To enter breakpoint debugging, first set a breakpoint on the processMapping method.

Enter the source code:


##

/** 
   * <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; 
  }

First we pass in the path we intercepted in the previous step , find ActionConfig through the findAction method of moduleConfig, and return ActionMapping. The specific code is:


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

If found, then the ActionMapping is stored in the context of the request. Code:


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

If the mapping is not found through the path, traverse the Actionconfig to find the mapping for the unknown path. If it is found, it will be stored in the request. If it is not found, , the error message is returned. The specific code is as follows:


// 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;

Let’s take a look at processActionForm, a method in ActionServlet. When we intercept the string, then according to the string After obtaining ActionMapping (which was introduced in the first two articles), we will use ActionMapping to create ActionForm, and put ActionForm in request or session for management.


Let’s first look at the specific implementation of the processActionForm method in struts:


/** 
   * <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); 
 
  
 
}

The general process of this method is: According to ActionMapping Search the ActionForm by its name. If ActionForm is configured, search it in the request or session. If there is an ActionForm that has been created in the request or session, it will be returned. If it does not exist, it will be created using reflection according to the completion path of the ActionForm, and then the created ActionForm will be placed in the request or session, and then the ActionForm will be returned.


Specifically, we can follow breakpoint debugging to see how this method runs.


Set a breakpoint first, and then enter the processActionForm method.


The first step is to create an ActionForm:

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

Generate an object from the ActionForm string in ActionMapping by calling the RequestUtils.createActionForm method. and return. Enter this code:


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

The method first defines the variable name and gets the value from mapping, String name = mapping.getName(); that is, we LoginForm string in the instance. Afterwards, the corresponding LoginForm string is generated into the corresponding object by calling FormBeanConfig config =moduleConfig.findFormBeanConfig(name);.


What I want to explain here is that we have configured such a label information in the struts-config configuration file:


<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中赋值了

The above is the detailed content of Struts1 ActionMapping example explanation. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Top 4 JavaScript Frameworks in 2025: React, Angular, Vue, SvelteTop 4 JavaScript Frameworks in 2025: React, Angular, Vue, SvelteMar 07, 2025 pm 06:09 PM

This article analyzes the top four JavaScript frameworks (React, Angular, Vue, Svelte) in 2025, comparing their performance, scalability, and future prospects. While all remain dominant due to strong communities and ecosystems, their relative popul

Spring Boot SnakeYAML 2.0 CVE-2022-1471 Issue FixedSpring Boot SnakeYAML 2.0 CVE-2022-1471 Issue FixedMar 07, 2025 pm 05:52 PM

This article addresses the CVE-2022-1471 vulnerability in SnakeYAML, a critical flaw allowing remote code execution. It details how upgrading Spring Boot applications to SnakeYAML 1.33 or later mitigates this risk, emphasizing that dependency updat

Node.js 20: Key Performance Boosts and New FeaturesNode.js 20: Key Performance Boosts and New FeaturesMar 07, 2025 pm 06:12 PM

Node.js 20 significantly enhances performance via V8 engine improvements, notably faster garbage collection and I/O. New features include better WebAssembly support and refined debugging tools, boosting developer productivity and application speed.

How do I implement multi-level caching in Java applications using libraries like Caffeine or Guava Cache?How do I implement multi-level caching in Java applications using libraries like Caffeine or Guava Cache?Mar 17, 2025 pm 05:44 PM

The article discusses implementing multi-level caching in Java using Caffeine and Guava Cache to enhance application performance. It covers setup, integration, and performance benefits, along with configuration and eviction policy management best pra

How does Java's classloading mechanism work, including different classloaders and their delegation models?How does Java's classloading mechanism work, including different classloaders and their delegation models?Mar 17, 2025 pm 05:35 PM

Java's classloading involves loading, linking, and initializing classes using a hierarchical system with Bootstrap, Extension, and Application classloaders. The parent delegation model ensures core classes are loaded first, affecting custom class loa

How to Share Data Between Steps in CucumberHow to Share Data Between Steps in CucumberMar 07, 2025 pm 05:55 PM

This article explores methods for sharing data between Cucumber steps, comparing scenario context, global variables, argument passing, and data structures. It emphasizes best practices for maintainability, including concise context use, descriptive

Iceberg: The Future of Data Lake TablesIceberg: The Future of Data Lake TablesMar 07, 2025 pm 06:31 PM

Iceberg, an open table format for large analytical datasets, improves data lake performance and scalability. It addresses limitations of Parquet/ORC through internal metadata management, enabling efficient schema evolution, time travel, concurrent w

How can I implement functional programming techniques in Java?How can I implement functional programming techniques in Java?Mar 11, 2025 pm 05:51 PM

This article explores integrating functional programming into Java using lambda expressions, Streams API, method references, and Optional. It highlights benefits like improved code readability and maintainability through conciseness and immutability

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Tools

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.