深入分析JavaWeb 43 -- Struts2开发入门

一、Struts2概述

1、Struts2是什么?

Struts2是一个M(模型—域–范围模型)V(View视图)C(控制器)框架(模型2)。框架都是一个半成品。提高开发效率。

Struts1是一个MVC框架,非常流行。有很大的缺点。此时一个webwork的框架设计超前,名气不是很大。Struts1+webworkd=struts2。用的是struts1的名字,但是与sruts1没啥关系,struts2的核心是webwork框架。

2、Struts2能干什么?

web开发Strust2 核心功能

  • 获取请求参数
  • 封装到JavaBean
  • 验证和转换
  • 调用业务代码存数据
  • 转向某个页面展示结果

是表现层的开发技术。(背景色为蓝色区域)

3、Struts2入门简单原理图

Filter VS Servlet

过滤器要比Servlet要强大,开发中经常用Servlet作为控制器,Filter也可以作为控制器来使用。

二、搭建struts2的开发环境

1、下载地址:http://struts.apache.org

2、解压后的目录结构:

a) apps:框架本身提供一些案例(学习)

b) docs:框架本身提供的文档(指南和API)。不保证100%正确

c) lib:框架需要的jar包及第三方的jar包(不要全拷贝)

d) src:源码

搭建步骤:

a、新建一个JavaWeb工程

b、拷贝struts2运行所需的必要jar包。(方便办法:struts2发行包\apps\struts-blank.war,拷贝其中的lib下的所有jar)

  • struts2-core-2.3.1.1.jar:Struts 2框架的核心类库
  • xwork-core-2.3.1.1.jar:Command模式框架,WebWork和Struts2都基于xwork
  • ognl-3.0.3.jar:对象图导航语言(Object Graph Navigation Language),

    struts2框架通过其读写对象的属性

  • freemarker-2.3.18.jar:Struts 2的UI标签的模板使用FreeMarker编写
  • commons-logging-1.1.x.jar:ASF出品的日志包,Struts 2框架使用这个日志

    包来支持Log4J和JDK 1.4+的日志记录。

  • commons-fileupload-1.2.2.jar: 文件上传组件,2.1.6版本后需要加入此文件
  • commons-io-2.0.1.jar:传文件依赖的jar包
  • commons-lang-2.5.jar:对java.lang包的增强,比如下面程序
if(str!=null&&!str.equals("")){

}
//增强的
if(StringUtils.isEmpty(str)){

}
  • javassist-3.11.0.GA.jar:动态代理的开发包。日本鬼子弄的(Jboss)。Hibernate也会用到

3、在web.xml中配置核心过滤器:StrutsPrepareAndExcuteFilter(框架提供)

  <filter>
    <filter-name>struct01</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struct01</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

4、在WEB-INF\classes目录下建立一个名称为struts.xml的配置文件。内容如下:(可以从struts2发行包\apps\struts-blank.war中拷贝)。抄头超屁股。。。。。。。。。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>

</struts>

5、把应用部署到Tomcat中,启动Tomcat,如果没有报错,说明搭建成功

三、第一个Struts2应用案例(编码步骤)

1、编写2个jsp

hello.jsp

  <body>
    <a href="${pageContext.request.contextPath}/hello.action">访问第一个Struts2案例</a>
  </body>

success.jsp

  <body>
    Struts2访问成功
  </body>

2、编写一个动作类(POJO,之前所谓的按照JavaBean规范编写的一个普通的类)

package xgp.struts.actions;

public class HelloAction {
    public String sayHello(){
        System.out.println("动作方法sayHello执行了,访问成功!");
        return "success";
    }
}

3、在struts.xml配置。告知控制器该实例化那个类,调用该类的那个方法,根据方法的返回值转向哪个页面

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <constant name="struts.devMode" value="true" />
    <package name="default" extends="struts-default">
        <action name="hello" class="xgp.struts.actions.HelloAction"
            method="sayHello">
            <result name="success" type="dispatcher">/success.jsp</result>
        </action>
    </package>
</struts>

4、访问测试:

http://localhost:8080/xgp.struts/hello.jsp

执行过程如下

四、执行过程和原理(可能面试题)

学习目标:熟知struts2的执行过程(下图记住)。源码可以不看

a、过滤器的初始化

1、StrutsPrepareAndExecuteFilter是一个过滤器,过滤器就有初始化方法

关键代码:57:dispatcher = init.initDispatcher(config);//初始化请求分发器。

2、InitOperations:

public Dispatcher initDispatcher( HostConfig filterConfig ) {
        Dispatcher dispatcher = createDispatcher(filterConfig);
        dispatcher.init();
        return dispatcher;
}
  • init_FileManager();
  • init_DefaultProperties(); // [1]
  • init_TraditionalXmlConfigurations(); // [2]
  • init_LegacyStrutsProperties(); // [3]
  • init_CustomConfigurationProviders(); // [5]
  • init_FilterInitParameters() ; // [6]
  • init_AliasStandardObjects() ; // [7]

Dispatcher:分发器

private void init_TraditionalXmlConfigurations() {
        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)) {
                    configurationManager.addContainerProvider(createXmlConfigurationProvider(file, false));
                } else {
                   configurationManager.addContainerProvider(createStrutsXmlConfigurationProvider(file, false, servletContext));
                }
            } else {
                throw new IllegalArgumentException("Invalid configuration file name");
            }
        }
    }

(重要)结论:

初始化过滤器时,会按顺序加载以下配置文件:

———-struts-default.xml,

———–struts-plugin.xml,

———-struts.xml这几个配置文件

———-struts-default.xml: struts2-core-**.jar包内部(框架内部的配置文件)

其中定义了一些Bean对象;有一个抽象的package,内部有一些结果类型,一些拦截器的定义,还有拦截器小组的定义。默认的拦截器小组名字是defaultStack。

———struts-plugin.xml:struts2提供的插件中(插件内部提供)

———struts-xml:程序员自己定义的(开发中经常搞)

b、过滤器的doFilter方法:用户的每次访问

1、ActionMapping mapping = prepare.findActionMapping(request, response, true);根据你的动作请求,从已经初始化好的配置文件中找对应的动作名称。

2、Dispatcher:

ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
                    namespace, name, method, extraContext, true, false);

五、Eclipse编写struts.xml没有提示的问题

原因:找不到约束文件

解决:

1、联网

2、手工配

a、eclipse的菜单:window\preferences

六、Struts2的配置文件

1、default.properties:在struts2-core-**.jar的org.apache.struts包中

关于Struts2一些常量配置(框架内部)

2、struts-default.xml:在struts2-core-**.jar中。(框架内部)

定义了一些bean;
定义了一个抽象的包:struts-default
定义了一些结果视图
定义了一些拦截器和拦截器小组

3、struts-plugin.xml :在struts2的第三方插件中(插件内部,给插件用的)Struts2-**-plugin.jar中

4、struts.xml:用户自己编写的(重点)

5、struts.properties :用户自己编写的(类路径中,不需要)key和value的形式

6、web.xml :struts2的一些配置可以写在这(Web应用中,不建议)

结论:1~6:后面的配置文件内容,会覆盖前面的。

比如:在struts.xml中覆盖default.properties中的内容,可以这么办:

<constant name="struts.action.extension" value="do"></constant> 

比如:在web.xml中把访问的扩展名改为xgp

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    <init-param>
        <param-name>struts.action.extension</param-name>
        <param-value>xgp</param-value>
    </init-param>
  </filter> 
<constant name="struts.devMode" value="true" />
<!-- Struts2中的一个常量,表示开发模式,当其值为true,如果配置文件内容改变,框架会重新加载而不需重新启动服务器!-->

6.1struts.xml中的package元素:

Struts-default.xml—–中有这么个包——<package name="struts-default" abstract="true"></package>

package:方便管理动作,作用:对应用中的动作进行模块化管理,就如同把类放在不同包中管理一样。

属性:

  • name:配置文件中保证package的唯一
  • namespace:取值一般以”/”开头,它与动作名称组成完成的访问路径。默认值是””。 http://域名+动作名称.action

如果配置了namespace那么访问资源时就要加上namespace:http://域名+namespace+动作名称.action

  • extends:父包名称。把父包中定义的内容完全集成下来。一般情况下,在struts2开发中需要继承(直接或间接)struts-default(struts-default.xml)
  • abstract:抽象包。抽象的东西就是设计被别人继承的。没有任何action子元素的packkage就可以定义为抽象的。

    package的namespace和动作访问专题:(小难点)

区分:namespace=”/”,实实在在的一个名称空间。绝对不是默认的:namespace=””或者不写,下面是具体的访问流程图

6.2 struts.xml中action元素的配置

作用:定义动作类

属性:

  • name:动作的名称,同一个包中的name必须唯一。
  • class:动作类的全名。可选属性。如果没有配置,则使用默认的class;默认值是ActionSupport Crtl+Shift+H搜索可得:com.opensymphony.xwork2.ActionSupport(可在源码中找到)

    因为struts-default.xml有指定。

<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
  • method:指定动作类中的哪个方法,可选的。默认值是execute

小知识:

可以在自己的package中通过以下标签,指定默认的动作类

<default-class-ref class="com.itheima.action.HelloAction"></default-class-ref>

6.3strutx.xml中的result元素的默认配置

作用:定义动作类执行完毕后转向的结果视图

属性:

  • name:结果视图的名称。与当前的动作类的动作方法返回值对应。默认值是success
  • type:结果视图的类型。默认是dispatcher(转发)

来自:struts-default.xml中的结果视图的定义。

6.4 struts2的一些常量含义及配置

如果你要改变这些常量,则在外面的配置文件struts.xml(或者别的配置文件中)修改,覆盖这些框架的默认值:

比如框架中

struts.action.extension=action, 框架要处理的后缀名称。如果需要改成以*.do或者*.doo结尾,则可以在Struts.xml中配置:

<constant name="struts.action.extension" value="do,doo"></constant>

在struts.properties中配置如下

struts.action.extension=do

在web.xml中配置如下

<filter>
    <filter-name>struct01</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    <init-param>
        <param-name>struts.action.extension</param-name>
        <param-value>do</param-value>
    </init-param>
 </filter> 

这里要注意配置文件的优先级.

常量

  • struts.i18n.encoding=UTF-8 框架使用的编码
  • struts.action.extension=action, 动作的访问后缀。多个可以使用逗号分隔
  • struts.serve.static.browserCache=true 指示浏览器是否缓存资源

    (原理:三个响应消息头:response.setHeader():Expires Cache-Control Pragma)

  • struts.configuration.xml.reload = true 是否在更改了struts.xml后自动重新加载。开发阶段有用。
  • struts.devMode = false 是否是开发模式。开发阶段建议为true。如果为true,struts.configuration.xml.reload就会为true
  • struts.ui.theme=xhtml 指定页面用的主题(struts标签时介绍)
  • struts.objectFactory = spring 默认情况,Action都是struts2框架给我们创建的(ObjectFactory,实例工厂)。与Spring框架整合时用。
  • struts.enable.DynamicMethodInvocation = false 是否允许DMI(动态方法调用:Dynamic Method Invocation)。
  • struts.multipart.maxSize=2097152 指定文件上传时的大小限制。2M

6.4配置文件分模块化

在项目开发中,为了更好的进行版本控制,经常引入外部的配置文件(比如在struts.xml同级目录下建立一个user.xml,则只需在

<include file="user.xml"></include>
时间: 2024-07-30 18:54:30

深入分析JavaWeb 43 -- Struts2开发入门的相关文章

深入分析JavaWeb 44 -- Struts2开发核心之动作类Action

一.Action动作类(一般用**Action结尾) struts2 的Action可以是POJO(Plain Old Java Object) 为了让用户开发的Action更加规范struts2提供了一个Action接口 通过method属性指定Action执行方法 没有指定method属性,默认执行execute方法 <action name="addCustomer" class="xgp.struts.actions.CustomerAction" /

深入分析JavaWeb 47 -- Struts2拦截器与文件上传下载

一.struts2中的拦截器(框架功能核心) 1.过滤器VS拦截器 过滤器VS拦截器功能是一回事.过滤器是Servlet规范中的技术,可以对请求和响应进行过滤. 拦截器是Struts2框架中的技术,实现AOP(面向切面)的编程思想,是可插拔的, 可以对访问某个 Action 方法之前或之后实施拦截. 拦截器栈(Interceptor Stack): 将拦截器按一定的顺序联结成一条链. 在访问被拦截的方法时, Struts2拦截器链中的拦截器就会按其之前定义的顺序被依次调用 Struts2执行原理

深入分析JavaWeb Item47 -- Struts2拦截器与文件上传下载

一.struts2中的拦截器(框架功能核心) 1.过滤器VS拦截器 过滤器VS拦截器功能是一回事. 过滤器是Servlet规范中的技术,能够对请求和响应进行过滤. 拦截器是Struts2框架中的技术.实现AOP(面向切面)的编程思想.是可插拔的, 能够对訪问某个 Action 方法之前或之后实施拦截. 拦截器栈(Interceptor Stack): 将拦截器按一定的顺序联结成一条链. 在訪问被拦截的方法时, Struts2拦截器链中的拦截器就会按其之前定义的顺序被依次调用 Struts2运行原

深入分析JavaWeb Item46 -- Struts2数据校验与国际化

1.用户输入数据的校验 1.校验方式 a:客户端校验.(防君子防不了小人)在页面中写js脚本. 这样做的好处是: 输入错误的话提醒比较及时: 减轻服务器的压力 b.服务器端校验. 数据安全 ,整个应用阻止非法数据的最后防线 而在实际开发中通常选择:a+b 2.服务器端数据校验: 1.编程式校验:自己Action中编写一个校验代码(缺点:验证规则都写在了代码中) 前提:动作类继承ActionSupport,重写Validateable接口中的validate()方法 ,在该方法中完成验证. 步骤如

深入分析JavaWeb 46 -- Struts2数据校验与国际化

1.用户输入数据的校验 1.校验方式 a:客户端校验.(防君子防不了小人)在页面中写js脚本. 这样做的好处是: 输入错误的话提醒比较及时: 减轻服务器的压力 b.服务器端校验. 数据安全 ,整个应用阻止非法数据的最后防线 而在实际开发中通常选择:a+b 2.服务器端数据校验: 1.编程式校验:自己Action中编写一个校验代码(缺点:验证规则都写在了代码中) 前提:动作类继承ActionSupport,重写Validateable接口中的validate()方法 ,在该方法中完成验证. 步骤如

深入分析JavaWeb Item27 -- JDBC学习入门

一.JDBC相关概念介绍 1.1.数据库驱动 这里的驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡,同样道理,我们安装好数据库之后,我们的应用程序也是不能直接使用数据库的,必须要通过相应的数据库驱动程序,通过驱动程序去和数据库打交道,如下所示: 1.2.JDBC介绍 SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范(接口),称之为JDBC.这套接口由数据库厂商去实现,这

深入分析JavaWeb Item5 -- Servlet开发

一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤: 1.编写一个Java类,实现servlet接口. 2.把开发好的Java类部署到web服务器中. 按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet 二.Servlet的运行过程 Servlet程序是由WEB

深入分析JavaWeb Item49 -- Struts2中常用标签与主题

一.非UI标签 1.property标签 property标签用于输出指定值: * default:可选属性, 如果需要输出的属性值为null,则显示该属性指定的值 * escape:可选属性,指定是否格式化HTML代码. * value: 可选属性,指定需要输出的属性值,如果没有指定该属性,则默认输出ValueStack栈顶的值. 2.set标签 set标签用于将某个值放入指定范围. var:变量的名字,name,id和var表达的含义是一样的,name,id被var替代 scope:指定变量

深入分析JavaWeb 48 -- Struts2中OGNL表达式与ValueStack

一.OGNL表达式 1.OGNL表达式介绍 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts2框架使用OGNL作为默认的表达式语言. OGNL相对其它表达式语言具有下面几大优势: 1.支持对象方法调用,如xxx.doSomeSpecial(): 2.支持类静态的方法调用和值访问,表达式的格式: @[类全名(包括包路径)]@[方法名 | 值名],例如:@[email protected]('foo %s', '