Struts2

一、struts2的执行流程

先来了解一下struts1的执行流程:

Struts1运行原理:(了解)

Struts2_第1张图片
Struts1运行原理:

Struts1工作流程:

(1)客户端向Web应用发送请求,请求被核心控制器ActionServlet拦截;

(2)ActionServlet根据请求决定是调用业务逻辑控制器还是将请求转发给相应JSP页面;

(3)若调用业务逻辑控制器,则业务逻辑控制器再调用相应的模型来处理用户的请求;

(4)处理的结果再通过JSP呈现给用户

Struts1缺点:

(1)Struts1仅支持JSP作为表现层技术

(2)在Model2的基础上发展得来,完全基于Servlet API,与Servlet API严重耦合,一旦脱离Web服务器,Action的测试将变得非常困难

(3)Action类必须继承其提供的Action基类,实现处理方法时又必须使用Struts1的专有API,这种入侵式设计的最大弱点在于:一旦系统需要重构,这些Action类将没有价值。

Struts2结合Webwork的优势:

(1)Struts2支持更多表现层技术,有更好的适应性。

(2)Action无须跟Servlet API耦合,使得测试更加容易,同时提高代码重用性;而且不耦合任何Servlet API(拦截器机制)

(3)Struts2具有更好的模块化和可扩展性(插件机制)。

Struts2的工作流程:

Struts2是以WebWork为核心,采用拦截器机制对用户的请求进行处理

工作流程:

Struts2_第2张图片
Struts2执行流程图

(1)客户端浏览器发送HTTP请求到Web应用

(2)Web容器将请求传递到标准ActionContextCleanUp过滤器以消除属性,而不让后续过滤器清楚,以延长Action中属性(包括自定义属性)的生命周期。

(3)再经过如stimesh等其他过滤器后,请求传递给StrutsPrepareAndExecuteFilter核心控制器

(4)StrutsPrepareAndExecuteFilter调用ActionMapper(Action映射器)确定调用哪个Action,再将控制权转移给ActionProxy代理

(5)ActionProxy代理调用配置管理器ConfigurationManager从配置文件struts.xml中读取配置信息,然后创建ActionInvocation对象

(6)ActionInvocation在调用拦截器链中的拦截器后再调用Action,根据Action返回的结果字符串查找对应的Result

(7)Result调用视图模板,再以相反的顺序执行拦截器链,返回HTTP响应

(8)HTTP响应以相反的顺序返回给核心控制器StrutsPrepareAndExecuteFilter以及其他web.xml中定义的过滤器,最终返回给客户端

或:

(1)客户端初始化一个指向Servlet容器(例如Tomcat)的请求

(2)这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin);

(3)接着StrutsPrepareAndExecuteFilter被调用,StrutsPrepareAndExecuteFilter询问ActionMapper来决定这个请求是否需要调用某个Action;

(4)如果ActionMapper决定需要调用某个Action,StrutsPrepareAndExecuteFilter把请求的处理交给ActionProxy;

(5)ActionProxy通过ConfigurationManager询问框架的配置文件,找到需要调用的Action类;

(6)ActionProxy创建一个ActionInvocation的实例。

(7)ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。

(8)一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2框架中继承的标签。在这个过程中需要涉及到ActionMapper。

Struts2核心组件介绍:

ActionMapper:通过method参数将请求转发到具体的action

ActionProxy代理:是Action的一个代理类,也就是说Action的调用是通过ActionProxy实现的,其实就是调用了ActionProxy.execute()方法,而该方法又调用了ActionInvocation.invoke()方法。归根到底,最后调用的是DefaultActionInvocation.invokeAction()方法。

ActionInvocation:就是Action的调用者。ActionInvocation在Action的执行过程中,负责Interceptor、Action和Result等一系列元素的调度。

Interceptor拦截器:是Struts 2的一个强有力的工具,有许多功能(feature)都是构建于它之上,如国际化、校验等。

二、介绍一下struts2(扯皮)

        Struts2是一个基于MVC设计模式的Web应用框架(Apache公司的,Apache公司的还有Tomcat),它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。

优势:

1.自动封装参数

2.参数的校验(配置)

3.结果的处理(转发|重定向)

4.国际化

5.解耦servlet

6.更好的支持MVC

7.防止表单的重复提交

三、使用struts2的准备工作

1、导入相对应的jar包 (struts2中的lib下的jar包);

2、在web.xml内进行配置filter(只有配置了filter才可以使用struts2框架)进行配置 StrutsPrepareAndExecuteFilter;所有的请求都被过滤器过滤到struts的配置文件中去。

Struts2_第3张图片
web.xml文件

3、配置我们的struts.xml文件  (放于根目录下)  (可以在struts的zip包中 抽出出来struts.xml文件 然后自己进行修改)

Struts2_第4张图片
struts.xml文件

4、创建相应的action进行操作;


Struts2_第5张图片
Action类

流程:当我们发送请求的时候,会被我们在web.xml中配置的拦截器进行拦截 会根据请求的路径在struts.xml中进行判断,在根据所对应的method执行性对应的方法.

四、struts.xml的配置信息

Struts2_第6张图片
struts.xml文件

配置剖析:

  package:

    name : 包名, 必须唯一

         namespace: 主要去action中的name属性进行联合,来确定一个action的访问路径

         extend:指定继承于哪个包,一般都是   struts-default(当是ajax返回一个json数据的时候,就是json-default包)

         abstruct:代表当前包是一个抽象包

     action:

    name: 与package中的namespace进行联合

    class:指示当前的action类

    method:指示当前类中的指定执行方法的执行方案

  result:

    name:与action中的返回值进行匹配 来确定要跳转的路径

    type:指定我们当前的要跳转的跳转方式

result的name属性默认值是success,

      默认的跳转方式是请求转发 dispatcher

五、在struts2中定义常量的方式

方式一:通过struts.xml配置文件,直接在struts.xml文件中配置(推荐)

Struts2_第7张图片
方式一

注:后加载的配置常量会将先加载的配置常量进行覆盖

方式二:通过struts.properties文件。新建一个struts.properties文件,与struts.xml同级,会自动加载这个文件,里面的key,value能够修改常量,但是struts加载这些文件的顺序一定:通常,Struts2框架按照如下搜索顺序加载Struts2常量。

⑴ struts-default.xml

⑵ struts-plugin.xml

⑶ struts.xml

⑷ struts.properties

⑸ web.xml

方式三:通过Web应用的web.xml文件。

当我们在web.xml文件中配置StrutsPrepareAndExecuteFilter时也可配置Struts2常量,此时采用为StrutsPrepareAndExecuteFilter配置初始化参数的方式来配置Struts2常量,如下所示:

Struts2_第8张图片

六、Action的创建

1、创建Action的方式:

(1)、创建POJO

(2)、实现Action接口

(3)、继承ActionSupport(一般使用这个)//具有丰富的功能,不过耦合性比较高

七、Struts2的封装数据

1.属性驱动 :在Action里面建立属性,写上get,set,属性名对应表单提交的字段名 支持类型:支持我们基本的八大数据类型以及其包装类和特定字符的转String

2.对象驱动 :创建对象属性,写上get,set,属性对应实体,表单里的字段要为属性.字段

3.模型驱动 :action要实现ModelDriven 接口,创建对象属性的实例,并在getModel方法里返回,表单中保持原有提交字段名(//缺点:只能对一个模型进行实例化

    步骤1.action实现modelDriven<类名> 接口

    步骤2.实例化模型(new )

              步骤3.重写getModel方法,并将我们实例的对象进行返回

附图解释:

Struts2_第9张图片
三种封装数据的图解

八、struts2中获取servletAPI 

1.ServletActionContext进行获取

一般使用这个

2.采用注入方式 :

ServletRequestAware,实现这个接口可以获取HttpServletRequest

ServletResponseAware ,实现这个接口可以获取HttpServletResponse

ServletContextAware实现这个接口可以获取ServletContext

九、OGNL表达式 

OGNL作用:

(1)、支持对象的操作,调用对象的方法

(2)、支持静态成员访问

(3)、支持赋值操作与表达串联

(4)、访问OGNL上下文,访问ActionContext

(5)、操作集合对象

三要素:

  (1)、表达式

        (2)、ognlContext上下文new OgnlContext()

  (3)、root根

获取数据

在root根中获取数据时 ,ognl表达式前不需要加  #, 如果不是在root根中进行获取数据,则需要添加 #

使用ognl

  在struts2中可以使用ognl+valueStack可以实现在页面上获取数据

       在页面中进行配置

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

来使用


Struts2_第10张图片

十、valueStack

valuestack的使用的主要目的是为了将action中产生的数据传递到页面上

struts2中的action是多例的,每一次请求都会创建一个action,一个valuestack对应一个action,valuesta贯穿整个action的生命周期

struts2框架将valuestack保存在 request中

  主要由两部分组成:

    CompoundRoot: 是一个list 主要存储的是action的相关数据

    Map context: 是一个map集合 主要引用web开发中的相关信息

       获取valuestack中的数据

     根据ognl表达式进行获取数据  如果前面添加# 在context中进行查找,如果没有添加# ,代表在CompoundRoot中进行获取数据,也就是所说的root中.

1.直接通过request对象进行获取  //因为valuestack存于request中

        servletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY)

2.使用actionContext进行获取

  ActionContext.getContext().getValueStack();

     ActionContext是action的上下文,struts2框架使用actionContext进行保存action在执行过程中所需要的一些对象

Struts2会根据每一次的http请求来创建对应的ActionContext,它是与当前线程绑定的。

  每一次请求,就是一个线程,对应着一个request,每一次请求,会创建一个Action,每一个action对应一个ActionContext.每一次请求也对应着一个valueStack.

request---ActionContext----Action-----ValueStaci它们都对应着一次请求(一个线程).

valueStack与ActionContext本质上是可以获取

 存储数据

//主要向root中进行存储

1.手动存储

       valueStack.set("key","value")

         valueStack.push()

2.自动存储

3.声明成员变量 提供get方法 为了使用属性封装也提供set方法 

  获取数据

      在标签中可以通过  value="key" 或 value="[index].top" 

底层是栈. 先进后出

    在action中的属性的get方法中 也可以将数据返回

    使用模型驱动

         在访问路径添加属性的赋值

              使用el表达式也可以获取数据   struts2 对 request 里面的 getattribute方法进行了增强

//个人理解: 如果对数据提供了get/set方法  那么就相当于属性存储,要使用ognl进行获取时,应该使用 对象名.属性名 进行获取

传递数据前提:继承了actionsupport

struts.xml文件中,用来传递数据 (在重定向中)     : 错误显示标签

在struts2中处理简单的信息 (字符串)this.addActionError

this.addFieldErrorthis.addActionMessage

十一、Interceptor拦截器

主要的作用是为了拦截 action 的操作,在action的执行前后进行一些我们想要做的操作

自定义拦截器

1.在配置文件中 声明 interceptor

2.创建一个类实现 interceptor接口

3.在action中使用interceptor ,action必须继承actionsupport

4.在action的配置中,引入自定义 interceptor

interceptor指定拦截action

    Interceptor的放行:  return invocation.invoke();

    在我们的配置文件中的interceptor里面

方法名

方法名

十二、文件上传

单文件上传:


jsp页面


Struts2_第11张图片
web.xml文件


Struts2_第12张图片
struts.xml配置文件
Struts2_第13张图片
Action

多文件上传:

Struts2_第14张图片
jsp页面


Struts2_第15张图片
web.xml文件


Struts2_第16张图片
struts.xml文件


Struts2_第17张图片
Action类


详细见:https://www.cnblogs.com/wkrbky/p/5904787.html

www.cnblogs.com/solverpeng/p/5613727.html

十三、文件下载

http://www.cnblogs.com/solverpeng/p/5613738.html

十四、表单的重复提交

www.cnblogs.com/solverpeng/p/5633360.html

你可能感兴趣的:(Struts2)