`
mujun1209
  • 浏览: 21105 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Struts2--Dispatcher&ConfigurationProvider

阅读更多

首先强调一下struts2的线程程安全,在Struts2中大量采用ThreadLocal线程局部变量的方法来保证线程的安全,像Dispatcher等都是通过ThreadLocal来保存变量值,使得每个线程都有自己独立的实例变量,互不相干.

 

接下来就从Dispatcher开始看起,先看其构造函数:

Java代码 复制代码
  1. //创建Dispatcher,此类是一个Delegate,它是真正完成根据url解析转向,读取对应Action的地方   
  2.     public Dispatcher(ServletContext servletContext, Map<String, String> initParams) {   
  3.         this.servletContext = servletContext;   
  4.         //配置在web.xml中的param参数   
  5.         this.initParams = initParams;   
  6.     }  
//创建Dispatcher,此类是一个Delegate,它是真正完成根据url解析转向,读取对应Action的地方
    public Dispatcher(ServletContext servletContext, Map<String, String> initParams) {
        this.servletContext = servletContext;
		//配置在web.xml中的param参数
        this.initParams = initParams;
    }

 

我们再看在FilterDispatcher创建Dispatcher的:

Java代码 复制代码
  1. protected Dispatcher createDispatcher(FilterConfig filterConfig) {   
  2.     Map<String, String> params = new HashMap<String, String>();   
  3.     for (Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements();) {   
  4.         String name = (String) e.nextElement();   
  5.         String value = filterConfig.getInitParameter(name);   
  6.         params.put(name, value);   
  7.     }   
  8. 都可以从FilterConfig中得到   
  9.     return new Dispatcher(filterConfig.getServletContext(), params);   
  10. }  
    protected Dispatcher createDispatcher(FilterConfig filterConfig) {
        Map<String, String> params = new HashMap<String, String>();
        for (Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements();) {
            String name = (String) e.nextElement();
            String value = filterConfig.getInitParameter(name);
            params.put(name, value);
        }
		//都可以从FilterConfig中得到
        return new Dispatcher(filterConfig.getServletContext(), params);
    }

 

创建Dispatcher之后,来看init()方法
init()方法是用来Load用户配置文件,资源文件以及默认的配置文件.

主要分七步走,看下面注释

Java代码 复制代码
  1.   public void init() {   
  2.   
  3.     if (configurationManager == null) {   
  4.     //设置ConfigurationManager的defaultFrameworkBeanName.   
  5.     //这里DEFAULT_BEAN_NAME为struts,这是xwork框架的内容,Framework可以是xwork,struts,webwork等   
  6.         configurationManager = new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);   
  7.     }   
  8.       //读取properties信息,默认的default.properties,   
  9.     init_DefaultProperties(); // [1]   
  10. //读取xml配置文件   
  11.       init_TraditionalXmlConfigurations(); // [2]   
  12. //读取用户自定义的struts.properties   
  13.       init_LegacyStrutsProperties(); // [3]   
  14. //自定义的configProviders   
  15.       init_CustomConfigurationProviders(); // [5]   
  16. //载入FilterDispatcher传进来的initParams   
  17.       init_FilterInitParameters() ; // [6]   
  18. //将配置文件中的bean与具体的类映射   
  19.       init_AliasStandardObjects() ; // [7]   
  20.          
  21. //构建一个用于依赖注射的Container对象   
  22. //在这里面会循环调用上面七个ConfigurationProvider的register方法   
  23. //其中的重点就是DefaultConfiguration的#reload()方法   
  24.       Container container = init_PreloadConfiguration();   
  25.       container.inject(this);   
  26.       init_CheckConfigurationReloading(container);   
  27.       init_CheckWebLogicWorkaround(container);   
  28.   
  29.       if (!dispatcherListeners.isEmpty()) {   
  30.           for (DispatcherListener l : dispatcherListeners) {   
  31.               l.dispatcherInitialized(this);   
  32.           }   
  33.       }   
  34.   }  
    public void init() {

    	if (configurationManager == null) {
		    //设置ConfigurationManager的defaultFrameworkBeanName.
			//这里DEFAULT_BEAN_NAME为struts,这是xwork框架的内容,Framework可以是xwork,struts,webwork等
    		configurationManager = new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
    	}
        //读取properties信息,默认的default.properties,
    	init_DefaultProperties(); // [1]
		//读取xml配置文件
        init_TraditionalXmlConfigurations(); // [2]
		//读取用户自定义的struts.properties
        init_LegacyStrutsProperties(); // [3]
		//自定义的configProviders
        init_CustomConfigurationProviders(); // [5]
		//载入FilterDispatcher传进来的initParams
        init_FilterInitParameters() ; // [6]
		//将配置文件中的bean与具体的类映射
        init_AliasStandardObjects() ; // [7]
        
		//构建一个用于依赖注射的Container对象
		//在这里面会循环调用上面七个ConfigurationProvider的register方法
		//其中的重点就是DefaultConfiguration的#reload()方法
        Container container = init_PreloadConfiguration();
        container.inject(this);
        init_CheckConfigurationReloading(container);
        init_CheckWebLogicWorkaround(container);

        if (!dispatcherListeners.isEmpty()) {
            for (DispatcherListener l : dispatcherListeners) {
                l.dispatcherInitialized(this);
            }
        }
    }

 

分七步载入各种配置属性,都是通过ConfigurationProvider接口进行的,这个接口提供init(),destroy(),register()等方法.
将各种ConfigurationProvider初始化之后将实例添加到ConfigurationManager的List里面.
最后通过循环调用List里的这些destroy(),register()等方法实现对配置文件的属性进行注册和销毁等功能.
下面将分析这七层功夫是怎样一步步练成的.

 

首先是init_DefaultProperties()

Java代码 复制代码
  1. private void init_DefaultProperties() {   
  2.     configurationManager.addConfigurationProvider(new DefaultPropertiesProvider());   
  3. }   
  4. 接来看DefaultPropertiesProvider好了,DefaultPropertiesProvider实际上只是实现了register()方法   
  5. public void register(ContainerBuilder builder, LocatableProperties props)   
  6.         throws ConfigurationException {   
  7.        
  8.     Settings defaultSettings = null;   
  9.     try {   
  10.         defaultSettings = new PropertiesSettings("org/apache/struts2/default");   
  11.     } catch (Exception e) {   
  12.         throw new ConfigurationException("Could not find or error in org/apache/struts2/default.properties", e);   
  13.     }   
  14.        
  15.     loadSettings(props, defaultSettings);   
  16. }  
    private void init_DefaultProperties() {
        configurationManager.addConfigurationProvider(new DefaultPropertiesProvider());
    }
	//直接来看DefaultPropertiesProvider好了,DefaultPropertiesProvider实际上只是实现了register()方法
    public void register(ContainerBuilder builder, LocatableProperties props)
            throws ConfigurationException {
        
        Settings defaultSettings = null;
        try {
            defaultSettings = new PropertiesSettings("org/apache/struts2/default");
        } catch (Exception e) {
            throw new ConfigurationException("Could not find or error in org/apache/struts2/default.properties", e);
        }
        
        loadSettings(props, defaultSettings);
    }

 

Java代码 复制代码
  1. //PropertiesSettings构造方法     
  2.     //读取org/apache/struts2/default.properties的配置信息,如果项目中需要覆盖,可以在classpath里的struts.properties里覆写   
  3.     public PropertiesSettings(String name) {   
  4.            
  5.         URL settingsUrl = ClassLoaderUtils.getResource(name + ".properties", getClass());   
  6.            
  7.         if (settingsUrl == null) {   
  8.             LOG.debug(name + ".properties missing");   
  9.             settings = new LocatableProperties();   
  10.             return;   
  11.         }   
  12.            
  13.         settings = new LocatableProperties(new LocationImpl(null, settingsUrl.toString()));   
  14.   
  15.         // Load settings   
  16.         InputStream in = null;   
  17.         try {   
  18.             in = settingsUrl.openStream();   
  19.             settings.load(in);   
  20.         } catch (IOException e) {   
  21.             throw new StrutsException("Could not load " + name + ".properties:" + e, e);   
  22.         } finally {   
  23.             if(in != null) {   
  24.                 try {   
  25.                     in.close();   
  26.                 } catch(IOException io) {   
  27.                     LOG.warn("Unable to close input stream", io);   
  28.                 }   
  29.             }   
  30.         }   
  31.     }   
  32.        
  33.     //loadSettings主要是将progerty的value和Locale从上面PropertiesSettings中取得并存放到LocatableProperties props   
  34.     //这个props是register的一个入参.   
  35.     protected void loadSettings(LocatableProperties props, final Settings settings) {   
  36.         // We are calling the impl methods to get around the single instance of Settings that is expected   
  37.         for (Iterator i = settings.listImpl(); i.hasNext(); ) {   
  38.             String name = (String) i.next();   
  39.             props.setProperty(name, settings.getImpl(name), settings.getLocationImpl(name));   
  40.         }   
  41.     }     
//PropertiesSettings构造方法  
    //读取org/apache/struts2/default.properties的配置信息,如果项目中需要覆盖,可以在classpath里的struts.properties里覆写
	public PropertiesSettings(String name) {
        
        URL settingsUrl = ClassLoaderUtils.getResource(name + ".properties", getClass());
        
        if (settingsUrl == null) {
            LOG.debug(name + ".properties missing");
            settings = new LocatableProperties();
            return;
        }
        
        settings = new LocatableProperties(new LocationImpl(null, settingsUrl.toString()));

        // Load settings
        InputStream in = null;
        try {
            in = settingsUrl.openStream();
            settings.load(in);
        } catch (IOException e) {
            throw new StrutsException("Could not load " + name + ".properties:" + e, e);
        } finally {
            if(in != null) {
                try {
                    in.close();
                } catch(IOException io) {
                    LOG.warn("Unable to close input stream", io);
                }
            }
        }
    }
	
	//loadSettings主要是将progerty的value和Locale从上面PropertiesSettings中取得并存放到LocatableProperties props
	//这个props是register的一个入参.
    protected void loadSettings(LocatableProperties props, final Settings settings) {
        // We are calling the impl methods to get around the single instance of Settings that is expected
        for (Iterator i = settings.listImpl(); i.hasNext(); ) {
            String name = (String) i.next();
            props.setProperty(name, settings.getImpl(name), settings.getLocationImpl(name));
        }
    }	

 

 

再来看第二步:init_TraditionalXmlConfigurations()

Java代码 复制代码
  1. private void init_TraditionalXmlConfigurations() {   
  2.  //首先读取web.xml中的config初始参数值      
  3.     //如果没有配置就使用默认的DEFAULT_CONFIGURATION_PATHS:"struts-default.xml,struts-plugin.xml,struts.xml",      
  4.     //这儿就可以看出为什么默认的配置文件必须取名为这三个名称了      
  5.     //如果不想使用默认的名称,直接在web.xml中配置config初始参数即可    
  6.     String configPaths = initParams.get("config");   
  7.     if (configPaths == null) {   
  8.         configPaths = DEFAULT_CONFIGURATION_PATHS;   
  9.     }   
  10.     String[] files = configPaths.split("\\s*[,]\\s*");   
  11.     for (String file : files) {   
  12.         if (file.endsWith(".xml")) {   
  13.             if ("xwork.xml".equals(file)) {   
  14.     //XmlConfigurationProvider负责解析xwork.xml   
  15.                 configurationManager.addConfigurationProvider(new XmlConfigurationProvider(file, false));   
  16.             } else {   
  17.     //其它xml都是由StrutsXmlConfigurationProvider来解析   
  18.                 configurationManager.addConfigurationProvider(new StrutsXmlConfigurationProvider(file, false, servletContext));   
  19.             }   
  20.         } else {   
  21.             throw new IllegalArgumentException("Invalid configuration file name");   
  22.         }   
  23.     }   
  24. }  
    private void init_TraditionalXmlConfigurations() {
	    //首先读取web.xml中的config初始参数值   
        //如果没有配置就使用默认的DEFAULT_CONFIGURATION_PATHS:"struts-default.xml,struts-plugin.xml,struts.xml",   
        //这儿就可以看出为什么默认的配置文件必须取名为这三个名称了   
        //如果不想使用默认的名称,直接在web.xml中配置config初始参数即可 
        String configPaths = initParams.get("config");
        if (configPaths == null) {
            configPaths = DEFAULT_CONFIGURATION_PATHS;
        }
        String[] files = configPaths.split("\\s*[,]\\s*");
        for (String file : files) {
            if (file.endsWith(".xml")) {
                if ("xwork.xml".equals(file)) {
				    //XmlConfigurationProvider负责解析xwork.xml
                    configurationManager.addConfigurationProvider(new XmlConfigurationProvider(file, false));
                } else {
				    //其它xml都是由StrutsXmlConfigurationProvider来解析
                    configurationManager.addConfigurationProvider(new StrutsXmlConfigurationProvider(file, false, servletContext));
                }
            } else {
                throw new IllegalArgumentException("Invalid configuration file name");
            }
        }
    }

 

对于其它配置文件只用StrutsXmlConfigurationProvider,此类继承XmlConfigurationProvider,而XmlConfigurationProvider又实现ConfigurationProvider接口。
类XmlConfigurationProvider负责配置文件的读取和解析,
首先通过init()中的loadDocuments(configFileName);利用DomHelper中的
public static Document parse(InputSource inputSource, Map<String, String> dtdMappings) 将configFileName配置文件通过SAX解析方式按照DtdMappings解析成Document对象.
然后通过Provider的register()方法加载"bean"和"constant"属性,再通过loadPackages()加载package及package中的属性
addAction()方法负责读取<action>标签,并将数据保存在ActionConfig中;
addResultTypes()方法负责将<result-type>标签转化为ResultTypeConfig对象;
loadInterceptors()方法负责将<interceptor>标签转化为InterceptorConfi对象;
loadInterceptorStack()方法负责将<interceptor-ref>标签转化为InterceptorStackConfig对象;
loadInterceptorStacks()方法负责将<interceptor-stack>标签转化成InterceptorStackConfig对象。
而上面的方法最终会被addPackage()方法调用,addPackage又会被Provider的loadPackages()调用,将所读取到的数据汇集到PackageConfig对象中。

Java代码 复制代码
  1.  protected PackageConfig addPackage(Element packageElement) throws ConfigurationException {   
  2.      PackageConfig.Builder newPackage = buildPackageContext(packageElement);   
  3.   
  4.      if (newPackage.isNeedsRefresh()) {   
  5.          return newPackage.build();   
  6.      }   
  7.      // add result types (and default result) to this package   
  8.      addResultTypes(newPackage, packageElement);   
  9.      // load the interceptors and interceptor stacks for this package   
  10.      loadInterceptors(newPackage, packageElement);   
  11.      // load the default interceptor reference for this package   
  12.      loadDefaultInterceptorRef(newPackage, packageElement);   
  13.      // load the default class ref for this package   
  14.      loadDefaultClassRef(newPackage, packageElement);   
  15.      // load the global result list for this package   
  16.      loadGlobalResults(newPackage, packageElement);   
  17.      // load the global exception handler list for this package   
  18.      loadGobalExceptionMappings(newPackage, packageElement);   
  19.      // get actions   
  20.      NodeList actionList = packageElement.getElementsByTagName("action");   
  21.      for (int i = 0; i < actionList.getLength(); i++) {   
  22.          Element actionElement = (Element) actionList.item(i);   
  23.          addAction(actionElement, newPackage);   
  24.      }   
  25.      // load the default action reference for this package   
  26.      loadDefaultActionRef(newPackage, packageElement);   
  27.      PackageConfig cfg = newPackage.build();   
  28.      configuration.addPackageConfig(cfg.getName(), cfg);   
  29.      return cfg;   
  30.  }     
  31.   
  32. loadConfigurationFiles解析读取xml中的内容   
  33.  private List<Document> loadConfigurationFiles(String fileName, Element includeElement) {         
  34.    ...     
  35. //通过DomHelper调用SAX进行解析xml   
  36. doc = DomHelper.parse(in, dtdMappings);   
  37. ...   
  38.    Element rootElement = doc.getDocumentElement();   
  39.    NodeList children = rootElement.getChildNodes();   
  40.    int childSize = children.getLength();   
  41.   
  42.    for (int i = 0; i < childSize; i++) {   
  43.      Node childNode = children.item(i);   
  44.   
  45.      if (childNode instanceof Element) {   
  46.        Element child = (Element) childNode;   
  47.   
  48.        final String nodeName = child.getNodeName();   
  49.   
  50.        if ("include".equals(nodeName)) {   
  51.          String includeFileName = child.getAttribute("file");   
  52.   
  53.       //解析每个action配置是,对于include文件可以使用通配符*来进行配置      
  54.          //如Struts.xml中可配置成<include file="actions_*.xml"/>     
  55.          if (includeFileName.indexOf('*') != -1) {   
  56.            ClassPathFinder wildcardFinder = new ClassPathFinder();   
  57.            wildcardFinder.setPattern(includeFileName);   
  58.            Vector<String> wildcardMatches = wildcardFinder.findMatches();   
  59.            for (String match : wildcardMatches) {   
  60.        //递归Load子file中的<include/>   
  61.              docs.addAll(loadConfigurationFiles(match, child));   
  62.            }   
  63.          } else {   
  64.   
  65.            docs.addAll(loadConfigurationFiles(includeFileName, child));   
  66.          }   
  67.        }   
  68.      }   
  69.    }   
  70.    docs.add(doc);   
  71.    loadedFileUrls.add(url.toString());   
  72.    ...   
  73.    return docs;   
  74.  }  
    protected PackageConfig addPackage(Element packageElement) throws ConfigurationException {
        PackageConfig.Builder newPackage = buildPackageContext(packageElement);

        if (newPackage.isNeedsRefresh()) {
            return newPackage.build();
        }
        // add result types (and default result) to this package
        addResultTypes(newPackage, packageElement);
        // load the interceptors and interceptor stacks for this package
        loadInterceptors(newPackage, packageElement);
        // load the default interceptor reference for this package
        loadDefaultInterceptorRef(newPackage, packageElement);
        // load the default class ref for this package
        loadDefaultClassRef(newPackage, packageElement);
        // load the global result list for this package
        loadGlobalResults(newPackage, packageElement);
        // load the global exception handler list for this package
        loadGobalExceptionMappings(newPackage, packageElement);
        // get actions
        NodeList actionList = packageElement.getElementsByTagName("action");
        for (int i = 0; i < actionList.getLength(); i++) {
            Element actionElement = (Element) actionList.item(i);
            addAction(actionElement, newPackage);
        }
        // load the default action reference for this package
        loadDefaultActionRef(newPackage, packageElement);
        PackageConfig cfg = newPackage.build();
        configuration.addPackageConfig(cfg.getName(), cfg);
        return cfg;
    }	
	
	//loadConfigurationFiles解析读取xml中的内容
    private List<Document> loadConfigurationFiles(String fileName, Element includeElement) {      
      ...  
	  //通过DomHelper调用SAX进行解析xml
	  doc = DomHelper.parse(in, dtdMappings);
	  ...
      Element rootElement = doc.getDocumentElement();
      NodeList children = rootElement.getChildNodes();
      int childSize = children.getLength();

      for (int i = 0; i < childSize; i++) {
        Node childNode = children.item(i);

        if (childNode instanceof Element) {
          Element child = (Element) childNode;

          final String nodeName = child.getNodeName();

          if ("include".equals(nodeName)) {
            String includeFileName = child.getAttribute("file");
			
	        //解析每个action配置是,对于include文件可以使用通配符*来进行配置   
            //如Struts.xml中可配置成<include file="actions_*.xml"/>  
            if (includeFileName.indexOf('*') != -1) {
              ClassPathFinder wildcardFinder = new ClassPathFinder();
              wildcardFinder.setPattern(includeFileName);
              Vector<String> wildcardMatches = wildcardFinder.findMatches();
              for (String match : wildcardMatches) {
		        //递归Load子file中的<include/>
                docs.addAll(loadConfigurationFiles(match, child));
              }
            } else {

              docs.addAll(loadConfigurationFiles(includeFileName, child));
            }
          }
        }
      }
      docs.add(doc);
      loadedFileUrls.add(url.toString());
      ...
      return docs;
    }

 

分享到:
评论
1 楼 nianien 2011-03-15  
你好,我怎么找不到哪个地方有写加载struts.properties文件的代码段呢?

相关推荐

    Struts2_s2-016&017&ognl2.6.11_patch漏洞补丁

    &lt;bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="myDefaultActionMapper" class="com.struts2.MyDefaultActionMapper" /&gt; &lt;constant name="struts.mapper.class" value=...

    struts2-core-2.0.11源码

    8. **请求处理(Request Handling)**:`org.apache.struts2.dispatcher.ng.filter`包中的`StrutsPrepareAndExecuteFilter`是Struts2与Servlet容器交互的关键,它负责准备请求并执行Action。 9. **类型转换(Type ...

    plexus-sec-dispatcher-1.3.jar

    plexus-sec-dispatcher-1.3.jar

    struts2漏洞s2-045,不升级jar版本的修补方法,已验证.docx

    3. 解压找到位置 org/apache/struts2/dispatcher/multipart:然后,我们需要解压源码包,找到 org/apache/struts2/dispatcher/multipart 目录。 4. 复制文件 JakartaMultiPartRequest.java、...

    struts2-blank

    Struts2是一个基于MVC(Model-View-Controller)设计模式的Java web应用程序框架,它在Java社区中广泛使用,特别是在开发企业级应用时。"struts2-blank"项目是一个基础的Struts2示例代码,可以帮助初学者快速理解和...

    struts2-lib.zip

    4. **结果类型**:Struts 2支持多种结果类型,如dispatcher(默认的JSP渲染),stream(处理文件下载),redirect(重定向URL)等,这些结果类型在Action配置中定义。 5. **标签库**:Struts 2提供了一系列的标签库...

    struts2-core-2.1.6.jar

    2. **Filter Dispatcher**:Struts2的核心是Filter Dispatcher,它是一个Servlet过滤器,负责拦截所有到达应用的HTTP请求。过滤器会根据配置决定是否将请求转发给Struts2框架处理,从而实现请求的分发。 3. **...

    解决struts2下载异常的jar包 struts2-sunspoter-stream-1.0.jar

    505) at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org....

    struts2配置2.5版

    org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter &lt;/filter-class&gt; &lt;filter-mapping&gt; &lt;!-- 拦截所有的url --&gt; &lt;filter-name&gt;struts2&lt;/filter-name&gt; &lt;url-pattern&gt;/*&lt;/url-...

    struts2版本 2.1.6 必须的jar包 和 web.xml 文件的修改

    1. **struts2-core.jar** - 包含Struts2框架的核心组件,如ActionContext、ActionProxy、Dispatcher等。 2. **struts2-convention-plugin.jar** - 提供了约定优于配置的特性,允许根据类名和方法名自动映射Action。 ...

    Struts2-注解第一个例子

    &lt;filter-class&gt;org.apache.struts2.dispatcher.FilterDispatcher&lt;/filter-class&gt; &lt;init-param&gt; &lt;param-name&gt;actionPackages&lt;/param-name&gt; &lt;param-value&gt;com.action&lt;/param-value&gt; &lt;/init-param&gt; &lt;filter-...

    struts2-core-lib.rar

    此外,Struts2还支持多种结果类型(Results),如dispatcher(默认的JSP渲染)、stream(用于文件下载)等。配置文件通常位于`struts.xml`或`struts-default.xml`中,定义了Action、结果类型、拦截器栈等。 总的来...

    Struts2-2.3-jar包

    再者,Struts2的Result类型允许开发者定义不同类型的响应,如dispatcher(重定向或转发到一个JSP页面)、stream(处理文件下载)和freemarker(使用FreeMarker模板引擎)。2.3版本进一步增强了对这些Result类型的...

    struts2-layout

    Struts2布局(Struts2-layout)是Apache Struts2框架的一个扩展,它提供了一种在Web应用中统一页面布局的方法。Struts2是Java Web开发中的一个流行MVC(模型-视图-控制器)框架,它简化了业务逻辑与表现层的分离,而...

    最新struts2-struts-2.3.4基础包

    2. **Dispatcher Servlet**: Struts2的核心控制器,负责接收HTTP请求,根据配置文件选择合适的Action执行,并将响应返回给客户端。 3. **Interceptor**: 拦截器是Struts2的一个重要特性,它允许在Action执行前后...

    struts2-2.3.15 jar包

    2. 配置web.xml:在Servlet容器的配置文件中,设置过滤器(`org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter`)以启用Struts2。 3. 创建Action类:继承自Struts2的Action接口或...

    struts2---jar包

    Struts2是一个强大的Java EE(Enterprise Edition)框架,主要用于构建基于MVC(Model-View-Controller)模式的Web应用程序。它的核心是Action类,通过它实现了业务逻辑与表现层的分离,增强了应用的可维护性和扩展...

    struts2-057-exp

    Struts2-057 EXP 是一个针对Apache Struts2框架的严重远程代码执行(RCE)漏洞,其CVE编号为CVE-2018-11776。这个漏洞影响了Struts2的多个版本,使得攻击者能够通过精心构造的HTTP请求在服务器端执行任意代码,从而...

    struts2-2.2.1-all 版本

    7. **结果类型**:Struts2支持多种结果类型,如dispatcher(用于转发到JSP页面)、stream(用于文件下载)等。 8. **异常处理**:通过全局异常映射,Struts2可以统一处理应用程序中的异常,提供一致的错误页面。 9...

    struts2-src

    1. **Action与Dispatcher**:在Struts2中,Action类是业务逻辑处理的主要载体。用户请求首先会被Struts2的前端控制器(DispatcherServlet)捕获,然后根据配置文件(struts.xml)中的映射信息,将请求分发到相应的...

Global site tag (gtag.js) - Google Analytics