Struts2

一 基本概念

1. 现有的Servlet的缺陷

2. Struts2框架

框架:软件开发中的“半成品”,是对现有的通用功能代码的封装,提高代码的复用性,提高软件开发的效率。

Struts2框架是Apache组织开发的开源的,基于MVC的框架。提供一新的控制器Action,用来替换原来的Servlet控制器

Servlet控制器和Acticon控制器的对比

二 搭建环境

  1. 引入Struts 2 框架所需要的各种jar包
  2. 将Struts.xml 配置文件放置在src 根目录下
  3. 初始化配置,在web.xml中配置核心过滤器
  4. 设置开发环境为utf-8,Struts2框架默认为UTF-8
配置核心过滤器

三 简单的Struts 2程序

public class FirstAction implements Action{
    @Override
    public String execute() throws Exception(){
        //需要执行的代码
        return "success";
    }
}

在struts.xml中,编写配置文件

配置Action

运行后,访问:https:// ip:port/项目名/action程序的name

四 Struts框架下的跳转方式

1. Action 跳转到 JSP

Struts框架默认的跳转方式,forward转发
redirect 重定向

2. Action 跳转到Action

chain转发,同一个请求
redirectAction,重定向,新的请求

五 请求参数的收集

1. 单个数据的收集

通过get和set进行赋值

2. 以对象的形式收集请求参数

通过对象属性的get和set进行赋值

3. 以集合或数组的形式收集复选框类的参数

在Struts的Action程序中如何获取Servlet里常见对象?
Struts2框架里提供了一个工具类ServletContext,通过这个类可以获取Servlet里的常见对象。
Struts里一个Action对象会产生多少个对象?
Servlet程序一个对象只产生一个,由这个对象为所有用户提供服务,Servlet是单例的
Struts框架会为每个请求创建一个action对象,Struts里的Action是多例的

六 Struts.xml 中package标签

package标签用在配置文件中,对Action的配置信息进行模块化管理,不影响程序的访问和功能。

namespace属性,用来对客户端的url请求进行模块化管理,便于后期维护功能的添加

注意:同一个namespace下的action之间跳转时,不需要指定namespace,直接给action的网名即可。

跨namespace跳转

跨namespace跳转

全局跳转

全局跳转

七 DMI动态方法调用

Struts框架允许在一个Action程序中,定义多个方法,以应对用户不同的功能需求。减少开发中action的数量,便于后期维护。

注意: action程序最好继承ActionSupport(不用再定义execute方法)所有业务方法(名字与execute不同,其他位置完全一样”)

编写Action时不再是实现Action接口,而是继承ActionSupport类,然后在配置文件中进行配置

DMI的通配符写法

DMI方式的收集参数的方式不变

八 OGNL表达式

Object-Graph Navigation Language,是一种表达式语言。Struts框架中使用OGNL技术来获取在值栈中的数据。

使用OGNL必须遵从其标准,OGNL只会从contextMap区和root区中取数据,所以值栈的内存结构为contextMap区和root区两部分,值栈后面会说到,这里先看OGNL如何进行取值。

获取root区数据

获取contextMap区数据

九 值栈 ValueStack

Struts提供了一个对象,用来存储和管理与一次请求相关的数据,这些数据可以存储在作用域中,作用域有,page、request、session、application

获取值栈对象

ActionContext actionContext = ActionContext.getContext();
ValueStack vs = actionContext.getValueStack();

值栈的内存结构

使用值栈存储数据

Struts2框架会在每次请求到达时,构建一个新的值栈对象,并且将新的request作用域的地址赋值给contextMap区request键保存,将原来的session作用域空间的地址赋值给新值栈对象的session键保存,application作用域也是如此。直接操作作用域和通过值栈存储数据的效果一样,两种方式都可以维护访问同一块内存数据。

十 Struts标签

Struts标签又来替换jsp页面中的脚本标签,使用之前需要导入

<%@taglib uri="/struts-tags" prefix="s"%

常见标签

<s:debug/> <!--用来查看struts里的值栈状态-->
<s:property value="ognl表达式"/> <!--根据OGNL获取指定的值,并且打印到浏览器-->
<s:if test="boolean值"> <!--条件判断-->
<s:else> <s:elseif test="boolean" >
<s:iterator value="ognl表达式获取到的集合或者数组数据">
<!-- 其他属性 begin   end   step status(index,count,even(是否是偶数次),odd(奇数次) )
每次循环的状态信息被保存在contextMap区 -- “#sta.index”
-->
循环输出
<s:date name=”ognl获取的日期值” format=”日期格式”/>
<!--如果只是展示,则任意format格式都ok,如果作为表单元素的默认value(可能会被提交的value)则最好定义为yyyy-MM-dd(struts处理日期的标准格式。)-->
<s:url> 
<!--功能1:将给定的资源的网名自动变成uri(自动添加应用名),功能2:检测浏览器是否支持cookie,如果不支持cookie,则自动将session的id拼接到生成的uri之后-->

十一 拦截器Interceptor

将action程序中的荣域代码(通用功能)提取出来,放在拦截器里完成,在请求到达action程序之前或者相应离开框架之前执行,等价于Servlet里的过滤器

注意:拦截器是双向拦截,拦截request和response,拦截器属于Struts框架,只会拦截action请求,不会拦截html、css等静态资源

拦截器的使用

1. 实现拦截器接口

实现Intrceptor接口

如果希望代码在action运行之后执行,可以将代码放置在invoke调用之后。如果自定义了拦截器,并且在action中引用自定义拦截器,则Struts框架不在为程序提供默认拦截器

2. 添加配置文件

struts.xml

3. 拦截器栈

当一个action程序需要通过多个拦截器时,为了简化声明,可以将多个拦截器做成拦截器栈,在action中引用。

配置拦截器栈

4. 默认拦截器栈

如果一个package标签中的所有action都需要使用一个拦截器栈,可以将这个拦截器栈设置为默认拦截器栈,一旦设置,会对本包中的所有的action生效

5. 拦截器体系

一旦用户自定义拦截器,则系统默认的不再生效,可以在定义的拦截器中引入系统默认的拦截器栈。

6. DMI中的拦截器

使用DMI时拦截器继承MethodFilterInterceptor

<interceptors>
	<!-- 先定义拦截器自己写的拦截器类 name随便写 class为全限定名 -->
	<interceptor name="filterInterceptor"class="com.bw.lanjieqi.FilterInterceptor"/>
 	<!-- 加到自己设置的拦截器栈里边去 -->
	 <interceptor-stack name="myStack">
		<!--   name为上面interceptor标签里面定义的name-->
		<interceptor-ref name="filterInterceptor">
		 <!--拦截器黑白名单   includeMethods为拦截的方法 excludeMethods不拦截这俩可以单独存在 -->
      		<param name="includeMethods">toAdd</param>
            <param name="excludeMethods">toUpdate</param>
            <!--指定参数name的值   可以不写不需要就不写-->
            <param name="name">FilterMethod</param>
       </interceptor-ref>
<!--   在自己配置的拦截器基础上,必须有struts2默认的拦截器,不然出错 -->
        <interceptor-ref name="defaultStack"></interceptor-ref>
    </interceptor-stack>
</interceptors>
 
<!-- 应用拦截器不写拦截器不生效 -->
 
<default-interceptor-ref name="myStack"/>

十二 配置文件拆分

十三 Action中的实例变量