Struts 源码学习之ActionServlet ( 一)

2023-10-25 15:38

本文主要是介绍Struts 源码学习之ActionServlet ( 一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Struts 源码最新版本为 struts-1.3.8-src.zip 12-Mar-2007 00:06

学习笔记使用struts-1.3.5-src.zip 的源码,

下载地址:http://archive.apache.org/dist/struts/source/

1.  web.xml中通过下面定义把所有的*.do交给ActionServlet处理

 

<!-- Standard Action Servlet Configuration (with debugging) -->

<servlet>

    <servlet-name>action</servlet-name>

    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

    <init-param>

      <param-name>config</param-name>

      <param-value>

          /WEB-INF/struts-config.xml,

          /WEB-INF/struts-config-Wildcard.xml

       </param-value>

    </init-param>

    <load-on-startup>2</load-on-startup>

  </servlet>

 

  <!-- Standard Action Servlet Mapping -->

  <servlet-mapping>

    <servlet-name>action</servlet-name>

    <url-pattern>*.do</url-pattern>

  </servlet-mapping>

 

2.  下面研究一下struts的源码,由于servlet设置了load-on-startup,所以tomcat启动时会加载ActionServlet,也就是会执行ActionServlet中的init()方法,Struts 的初始化实现就是在这里实现的

 

注: 由于servlet的生命周期为 web容器加载和实例化类/init()初始化/service()请求处理/destroy()四个阶段,而init()方法在tomcat启动后只执行一次,所以如果想在tomcat启动后用debug模式查看ActionServletinit()方法的执行,可以把上面的<load-on-startup>2</load-on-startup>注释掉就可以了(不过真正开发时还是需要的)。

 

3.  ActionServlet中定义了一些常量,如下:

    // 默认的struts配置文件为/WEB-INF/struts-config.xml

    protected String config = "/WEB-INF/struts-config.xml"; // initOther(); initModuleConfig ();

 

    // 默认的链(定义了一个按顺序执行的处理流程)配置文件

protected String chainConfig = "org/apache/struts/chain/chain-config.xml";

// initChain();

 

protected Digester configDigester = null; // initModuleConfig ();

// convertNulltrueJava包装类(如java.lang.Integer)的初始值为null

protected boolean convertNull = false; // initOther();

 

protected MessageResources internal = null; // initInternal();

// 默认的 struts-core-1.3.5.jar 包 中资源文件为ActionResources.properties

protected String internalName = "org.apache.struts.action.ActionResources";

// initInternal();

 

// 一些文档类型定义,用来验证相应的配置文件如struts-config.xml是否正确

    protected String[] registrations =

        {

            "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN",

            "/org/apache/struts/resources/struts-config_1_0.dtd",

            "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN",

            "/org/apache/struts/resources/struts-config_1_1.dtd",

            "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN",

            "/org/apache/struts/resources/struts-config_1_2.dtd",

            "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN",

            "/org/apache/struts/resources/struts-config_1_3.dtd",

            "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",

            "/org/apache/struts/resources/web-app_2_3.dtd"

        }; // initServlet();

    protected String servletMapping = null; // initServlet();

protected String servletName = null; // initServlet();

 

4.  ActionServlet 中的init()方法执行流程如下

 

 

① 内部资源文件 ActionResources.properties 的初始化 initInternal();

protected MessageResources internal = null; // initInternal();

protected String internalName = "org.apache.struts.action.ActionResources"; // initInternal();

 

// initInternal 方法中通过下面得到一个MessageResources对象

internal = MessageResources.getMessageResources(internalName);

此资源文件主要包括一些消息信息的定义,具体可参考org.apache.struts.action下的ActionResources.properties文件

 

MessageResources.java中的getMessageResources方法,

        if (defaultFactory == null) {

            defaultFactory = MessageResourcesFactory.createFactory(); //

        }

        return defaultFactory.createResources(config); // 传入internalName //

 

MessageResourcesFactory.createFactory() 所做的工作:

protected static transient Class clazz = null;

protected static String factoryClass =

        "org.apache.struts.util.PropertyMessageResourcesFactory";

clazz = RequestUtils.applicationClass(factoryClass);

RequestUtils.applicationClass通过classLoader加载一个

org.apache.struts.util.PropertyMessageResourcesFactory

 

defaultFactory.createResources(config) 所做的工作:

this.factory = factory;

("org.apache.struts.util.PropertyMessageResourcesFactory")

this.config = config;("org.apache.struts.action.ActionResources")

this.returnNull = returnNull;(true)

PropertyMessageResourcesFactory extends MessageResourcesFactory

返回一个MessageResources对象

 

 

② 调用 initOther(); web.xml中加载ActionServlet的初始化参数,包括config/ convertNull

protected String config = "/WEB-INF/struts-config.xml"; // initOther();

protected boolean convertNull = false; // initOther();

 

// 得到web.xml"config"参数

String value;

value = getServletConfig().getInitParameter("config");

if (value != null) {

    config = value;

}

    <servlet>

        <servlet-name>action</servlet-name>

        <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

        <init-param>

            <param-name>config</param-name>   <!-- 得到"config"参数-->

            <param-value>/WEB-INF/struts-config.xml</param-value>

        </init-param>

        <init-param>

            <param-name>convertNull</param-name>   <!-- 得到"convertNull"参数-->

            <param-value>true</param-value>

        </init-param>

        .......

    </servlet>   

 

// 获得convertNull的值(true/yes/on/y/1

getServletConfig().getInitParameter("convertNull");

如果这个参数的值为 truetrue/yes/on/y/1, 数值型(BigDecimal/BigInteger/Boolean/Byte/Character/Double/Float/Integer/Long/Short)Java 包装类(比如java.lang.Integer)的初始值为null,而非0。缺省值[false]

 

使其初始值为null的方法如下:

// 将所有的转换器注销掉

ConvertUtils.deregister();

// 为指定类型clazz注册转换器converter

ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class);

ConvertUtils.register(new BigIntegerConverter(null),BigInteger.class);

.......

 

注: ConvertUtils 用法如下

deregister () deregister (java.lang.Class clazz)

注销转换器,前者将所有的转换器注销掉,后者只注销对应于clazz的转换器register( Converter  converter, java.lang.Class clazz)

为指定类型clazz注册转换器converter。如果clazz已经存在一个对应的转换器,那么converter覆盖原来的转换器。

这篇关于Struts 源码学习之ActionServlet ( 一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/283509

相关文章

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操