Struts2是一个基于MVC设计模式的Web应用框架,它本质上至关于一个servlet,在MVC设计模式中,Struts2做为控制器(Controller)来创建模型与视图的数据交互。Struts2在Struts1融合webwork。前端
ONGL表达式:就是对象图形化导航语言,在前端页面中,访问action的属性、方法;相似于认为就是对JSP的封装,是编程更加方便。(如下详解)java
一个基本概念上的结构,用于去解决或者处理复杂的问题,框架是在特定的领域内解决问题。web
框架的优势:spring
(1)重用代码大大增长,软件生产效率和质量也获得了提升apache
(2)使用框架开发,它提供统一的标准,大大下降了咱们的后期维护。编程
工做流程:
(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) struts2核心部分源代码org.apache.struts2xx : src\core\src\main\java浏览器
(2) struts2的xwork核心部分源代码 :src\xwork-core\src\main\java\com\opensymphony\xwork2缓存
(3)struts2的插件的源代码: src\plugins安全
2.关于struts.xml的中文乱码
第一步:
在eclipse的window下首选面中查找xml catalog
第二步:
Location:配置本地的dtd文件路径
key type:选择URI
Key: http://struts.apache.org/dtds/struts-2.3.dtd
注意版本要对应,若是你能够上网,那么会自动缓存dtd,具备提示功能。
3.执行流程介绍
1.当经过浏览器发送一个请求
2.会被StrutsPrepareAndExecuteFilter拦截
3.会调用struts2框架默认的拦截器(interceptor)完成部分功能
4.在执行Action中操做
5.根据Action中方法的执行结果来选择来跳转页面Resutl视图通常管StrutsPrepareAndExecuteFilter叫作前端控制器(核心控制器),只有配置了这个filter,Struts2框架才能使 用,Struts2的默认拦截器(interceptor)它们是在struts-default.xml文件中配置。
注意:这上xml文件是在struts-core.jar包中,默认的拦截器是在defaultStack中定义的。
init_DefaultProperties()加载的是 default.properties 文件
位置:struts2-core.jar 包 org.apache.struts2 包下
做用:主要是声明了 struts2 框架的常量
init_TraditionXmlConfigurations()加载的是一批配置文件
Struts-default.xml
位置:struts2-corl.jar
做用:声明了 interceptor result bean
Struts-plugin.xml
位置:在 struts2 的插件包中
做用:主要用于插件的配置声明
Struts.xml
位置:在咱们本身的工程中
做用:用于咱们本身工程使用 struts2 框架的配置
init_LegacyStrutsProperties()加载的是自定义的struts.properties
位置:都是在本身工程的 src 下
做用:定制常量
init_CustomConfigurationProviders()自定义配置提供
init_FilterInitParmeters()加载的是 web.xml 配置文件
主要是加载 struts2 框架在 web.xml 文件中的相关配置.
init_AliasStandardObjects() bean 相关配置
重点掌握:
1.Default.properties
2.Struts-default.xml
3.Struts-plugin.xml
4.Struts.xml
5.web.xml
2.struts.xml件配置介绍
(1) package配置(strust.xml只存在一个package至关于一个struts的项目)
name属性做用:定义一个包的名称,它必须惟一。
namespace属性做用:主要是与action标签的name属性联合使用来肯定一个 action的访问路径。
extends属性做用:指定继承自哪一个包。通常值是struts-default,struts-default包是 在struts-default.xml文件中声明的。
abstruct属性它表明当前包是一个抽象的,主要是用于被继承。
(2) action配置(对应相应的以action结尾的类,一个package能够有多个action)
name属性做用:主要是与package的namespace联合使用来肯定action的访问路径。
class属性做用:用于指示当前的action类。
method属性做用:用于指示当前的action类中的哪一个方法执行。
(3) result配置(用于显示视图的结果)
name属性做用是与action类的method方法的返回值进行匹配,来肯定跳转路径。
type属性做用是用于指定跳转方式。
Action类至关于javaWeb阶段下的Servlet类,作着调用service层的关系,实现页面的 跳转,完成业务逻辑操做。
(1) 建立一个POJO类;(hibernate自动会封装成PO类)
(2) 建立一个类实现一个Action接口;
(3) 建立一个类继承ActionSupport类。
(1) 直接经过<action>标签来配置,经过method来指定访问的方法,若是method没有,默认访问的是execute方法;
(2) 简化的 action 访问方式,可使用*通配符来访问,使用*来简化操做方案,它对名称规范必须进行一个统一。
直接在 action 类中提供与请求参数匹配属性,提供get/set方法在, action 类中创始一个javaBean,对其提供get/set,在请求时页面上要进行修改,例如 user.username user.password ,要使用ognl表达式
以上两种方式的优缺点:
第一种比较简单,在实际操做咱们须要将action的属性在赋值给模型(javaBean)去操做;
第二种:不须要在直接将值给javaBean过程,由于直接将数据封装到javaBean中。它要求在页面上必须使用ognl表达式,就存在页面不通用问题。
(1)让 Action 类要实现一个指定接口 ModelDriven;
(2)实例化模型对象(就是要new出来javaBean);
(3)重写getModel方法将实例化的模型返回。
获取request: ServletActionContext.getRequest();
获取response: ServletActionContext.getResponse();
获取servletContext: ServletActionContext.getServletContext();
Struts2框架在运行时,请求会被StrutsPrepareAndExecuteFilter拦截,会根据请求,去strtus.xml文件中查找到匹配的action,在action执行前,会走一些interceptor默认执行的拦截器是struts-default.xml文件中定义的,在默认执行的拦截器中有一个。
ServletRequestAware, 实现这个接口能够获取HttpServletRequest;
ServletResponseAware ,实现这个接口能够获取HttpServletResponse;
ServletContextAware 实现这个接口能够获取ServletContext;
OGNL是Object-Graph Navigation Language(对象图导航语言)的缩写,它是一种功能强大的表达式语言,经过它简单一致的表达式语法,能够存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
Struts2框架内置了OGNL,OGNL自己也是一个项目,它是能够单独使用。
OGNL做用:
支持对象的操做,调用对象的方法;
支持静态成员访问;
支持赋值操做与表达串联;
访问OGNL上下文,访问ActionContext;
操做集合对象。
Strtus2框架中如何使用ognl表达式
在struts2框架中咱们使用ognl表达式的做用是从valueStack中获取数据,在struts2框架中可使用ognl+valueStack达到在页面(jsp)上来获取相关的数据,要想在jsp页面上使用ognl表达式,就须要结合struts2框架的标签<s:property value=”表达式”>来使用。
valueStack的主要目的是为action中产生的数据携带到页面上,也就是说valueStack它就是一个容器,在Struts2框架中将valueStack设计成一个接口,当客户端向咱们发送一个请求,服务器就会创始一个Action来处理请求,struts2中的action是一个多例,每一次请求都会有一个新的action对应。因此它不存在线程安全问题,一个valueStack对应一个action,valueStack贯穿整个action的生命周期,struts2框架将valueStack保存在request中。
valueStack主要有两部分组成:
CompoundRoot:它就是一个ArrayList它主要存储的是action的相关数据;
Map<String,Object> context:就是一个Map,Context中主要存储了一些引用,这个引用主要是关于web开发中相关信息;
pameters :请求参数;
request:请求对象中全部属性;
session:会话对象中全部属性;
application:application对象中的全部发展;
在struts2框架中咱们经过ognl表达式来获取valueStack中数据,没有使用#就会从CompoundRoot中获取数据,若是使用#来获取,这时就会从context中来获取。
(1) 经过request对象来获取;
ValueStack vs = (ValueStack)ServletActionContext.getRequest()
.getAttribute(ServletActionContext.STURTS_VALUESTACK_KEY);
(2) 经过ActionContext来获取
ValueStack vs = ActionContext.getServletContext()getValueStack();
ActionContext它是action上下文,Strtus2框架它使用ActionContext来保存Action在执行过程当中所须要的一些对象,例如 session, application… ActionContext的获取 是经过它的静态方法getContext()获得。Struts2会根据每一次的http请求来建立对应的ActionContext,它是与当前线程绑定的。每一次请求,就是一个线程,对应着一个request,每一次请求,会建立一个Action,每个action对应一个ActionContext.每一次请求也对应着一个valueStack。它们都对应着一次请求(一个线程),valueStack与ActionContext本质上是能够获取。
(1) 手动向valueStack存储数据;
vs.push(String str); 和 vs.set(Object obj String str);
(2) Struts2框架自动向valueStack中存储数据;
每次请求,访问action,这个对象会存储到valueStack中。
在DefaultActionInvocation的init方法内,调用:vs.push(Action action);
在ModelDrivernInterceptor中,调用ModelDrivern的getModel()方法;
(1). Jsp页面获取,导入s标签库
<s:property value = “ “ />
(2). 在Action中属性
调用PO类getter方法;
(3). 在Model类中(即模型驱动)
调用getModel()方法;
El表达式能够从valueStack中获取信息,在jsp页面中显示:如:{$ model.name},org.apache.struts2.dispatcher.StrutsRequestWrapper这个类可使ValueStack使用EL表达式,Struts2框架对request进行了加强,重写了getAttribute方法,若是在request域中查找不到数据,就会在valueStack中获取。
OGNL是一般要结合Struts 2的标志一块儿使用。主要是#、%和$这三个符号的使用,#号:它是从非root中获取数据,%号用于强制是否要解析ognl表达式,$号主要是从配置文件中来获取valueStack中数据。
Struts2中的interceptor它是基于spring aop思想,而aop思想它本质上是经过动态代理来实现。咱们strtus2的拦截器它主要是拦截Action的操做,在action的执行前或执行后进行一些其它的功能操做。
拦截器链(拦截器栈)简单说,就是能够将多个拦截器造成一个链,在访问它们时依次访问。执行图见上图;
执行的过程:
当咱们发送请求访问Action时,会被StrutsPrepareAndExecuteFilter拦截在其doFilter方法内执行了execute.executeAction(request, response, mapping);这个代码执行后dispatcher.serviceAction(request, response, mapping);serviceAction方法执行在这个方法执行过程当中会建立Action代理对象ActionProxy proxy = getContainer().getInstance(ActionProxyFactory.class).createActionProxy( namespace, name, method, extraContext, true, false);经过proxy去执行了proxy.execute();在execute方法内return invocation.invoke();invocation它是ActionInvocation一个对象。会去加载咱们的配置文件,将配置文件中全部的interceptor获得进行遍历。在struts-default.xml文件中定义了默认加载的拦截器栈 defaultStack,在每个拦截器的interceptor方法内,又调用了DefaultActionInvocation的invoke方法,其实就是递归调用。
全部的Interceptor都要实现一个接口,在配置文件中声明Interceptor,能够将多个interceptor封装成一个stack,能够在Action的配置中引入本身的interceptor,在使用时name也能够引入一个interceptor stack。注意:当咱们显示的引入了一个自定义的Interceptor,那么默认的defaultStack就不会在导入,须要手动导入。
@Namespace来代替<package namespace=””>
@ParentPackage来代替<package extends=””>
@Action来描述关于<action>配置
value属性<action name=””>
使用@Action的results来描述关于结果类型的配置<result>
<result name=”” type=””>
@Action(results={@Result(name=””,type=””,location=””)})
@Actions
做用:能够经过多个映射来访问同一个action;
@Results
相似于全局的结果视图;
@InterceptorRef
它是用于处理拦截器的;
Struts2是一个基于MVC设计模式的Web应用框架,它本质上至关于一个servlet,在MVC设计模式中,Struts2做为控制器(Controller)来创建模型与视图的数据交互。Struts2在Struts1融合webwork。
ONGL表达式:就是对象图形化导航语言,在前端页面中,访问action的属性、方法;相似于认为就是对JSP的封装,是编程更加方便。(如下详解)
一个基本概念上的结构,用于去解决或者处理复杂的问题,框架是在特定的领域内解决问题。
框架的优势:
(1)重用代码大大增长,软件生产效率和质量也获得了提升
(2)使用框架开发,它提供统一的标准,大大下降了咱们的后期维护。
工做流程:
(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) struts2核心部分源代码org.apache.struts2xx : src\core\src\main\java
(2) struts2的xwork核心部分源代码 :
src\xwork-core\src\main\java\com\opensymphony\xwork2
(3)struts2的插件的源代码: src\plugins
第一步:
在eclipse的window下首选面中查找xml catalog
第二步:
Location:配置本地的dtd文件路径
key type:选择URI
Key: http://struts.apache.org/dtds/struts-2.3.dtd
注意版本要对应,若是你能够上网,那么会自动缓存dtd,具备提示功能。
1.当经过浏览器发送一个请求
2.会被StrutsPrepareAndExecuteFilter拦截
3.会调用struts2框架默认的拦截器(interceptor)完成部分功能
4.在执行Action中操做
5.根据Action中方法的执行结果来选择来跳转页面Resutl视图通常管StrutsPrepareAndExecuteFilter叫作前端控制器(核心控制器),只有配置了这个filter,Struts2框架才能使用,Struts2的默认拦截器(interceptor)它们是在struts-default.xml文件中配置。
注意:这上xml文件是在struts-core.jar包中,默认的拦截器是在defaultStack中定义的。
init_DefaultProperties()加载的是 default.properties 文件
位置:struts2-core.jar 包 org.apache.struts2 包下
做用:主要是声明了 struts2 框架的常量
init_TraditionXmlConfigurations()加载的是一批配置文件
Struts-default.xml
位置:struts2-corl.jar
做用:声明了 interceptor result bean
Struts-plugin.xml
位置:在 struts2 的插件包中
做用:主要用于插件的配置声明
Struts.xml
位置:在咱们本身的工程中
做用:用于咱们本身工程使用 struts2 框架的配置
init_LegacyStrutsProperties()加载的是自定义的struts.properties
位置:都是在本身工程的 src 下
做用:定制常量
init_CustomConfigurationProviders()自定义配置提供
init_FilterInitParmeters()加载的是 web.xml 配置文件
主要是加载 struts2 框架在 web.xml 文件中的相关配置.
init_AliasStandardObjects() bean 相关配置
重点掌握:
1.Default.properties
2.Struts-default.xml
3.Struts-plugin.xml
4.Struts.xml
5.web.xml
2.struts.xml件配置介绍
(1) package配置(strust.xml只存在一个package至关于一个struts的项目)
name属性做用:定义一个包的名称,它必须惟一。
namespace属性做用:主要是与action标签的name属性联合使用来肯定一个 action的访问路径。
extends属性做用:指定继承自哪一个包。通常值是struts-default,struts-default包是 在struts-default.xml文件中声明的。
abstruct属性它表明当前包是一个抽象的,主要是用于被继承。
(2) action配置(对应相应的以action结尾的类,一个package能够有多个action)
name属性做用:主要是与package的namespace联合使用来肯定action的访问路径。
class属性做用:用于指示当前的action类。
method属性做用:用于指示当前的action类中的哪一个方法执行。
(3) result配置(用于显示视图的结果)
name属性做用是与action类的method方法的返回值进行匹配,来肯定跳转路径。
type属性做用是用于指定跳转方式。
Action类至关于javaWeb阶段下的Servlet类,作着调用service层的关系,实现页面的 跳转,完成业务逻辑操做。
(1) 建立一个POJO类;(hibernate自动会封装成PO类)
(2) 建立一个类实现一个Action接口;
(3) 建立一个类继承ActionSupport类。
(1) 直接经过<action>标签来配置,经过method来指定访问的方法,若是method没有,默认访问的是execute方法;
(2) 简化的 action 访问方式,可使用*通配符来访问,使用*来简化操做方案,它对名称规范必须进行一个统一。
直接在 action 类中提供与请求参数匹配属性,提供get/set方法
在 action 类中创始一个javaBean,对其提供get/set,在请求时页面上要进行修改,
例如 user.username user.password ,要使用ognl表达式
以上两种方式的优缺点:
第一种比较简单,在实际操做咱们须要将action的属性在赋值给模型(javaBean)
去操做;
第二种:不须要在直接将值给javaBean过程,由于直接将数据封装到javaBean
中。它要求在页面上必须使用ognl表达式,就存在页面不通用问题。
(1)让 Action 类要实现一个指定接口 ModelDriven;
(2)实例化模型对象(就是要new出来javaBean);
(3)重写getModel方法将实例化的模型返回。
获取request: ServletActionContext.getRequest();
获取response: ServletActionContext.getResponse();
获取servletContext: ServletActionContext.getServletContext();
Struts2框架在运行时,请求会被StrutsPrepareAndExecuteFilter拦截,会根据请求,去strtus.xml文件中查找到匹配的action,在action执行前,会走一些interceptor默认执行的拦截器是struts-default.xml文件中定义的,在默认执行的拦截器中有一个。
ServletRequestAware, 实现这个接口能够获取HttpServletRequest;
ServletResponseAware ,实现这个接口能够获取HttpServletResponse;
ServletContextAware 实现这个接口能够获取ServletContext;
OGNL是Object-Graph Navigation Language(对象图导航语言)的缩写,它是一种功能强大的表达式语言,经过它简单一致的表达式语法,能够存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
Struts2框架内置了OGNL,OGNL自己也是一个项目,它是能够单独使用。
OGNL做用:
支持对象的操做,调用对象的方法;
支持静态成员访问;
支持赋值操做与表达串联;
访问OGNL上下文,访问ActionContext;
操做集合对象。
Strtus2框架中如何使用ognl表达式
在struts2框架中咱们使用ognl表达式的做用是从valueStack中获取数据,在struts2框架中可使用ognl+valueStack达到在页面(jsp)上来获取相关的数据,要想在jsp页面上使用ognl表达式,就须要结合struts2框架的标签<s:property value=”表达式”>来使用。
valueStack的主要目的是为action中产生的数据携带到页面上,也就是说valueStack它就是一个容器,在Struts2框架中将valueStack设计成一个接口,当客户端向咱们发送一个请求,服务器就会创始一个Action来处理请求,struts2中的action是一个多例,每一次请求都会有一个新的action对应。因此它不存在线程安全问题,一个valueStack对应一个action,valueStack贯穿整个action的生命周期,struts2框架将valueStack保存在request中。
valueStack主要有两部分组成:
CompoundRoot:它就是一个ArrayList它主要存储的是action的相关数据;
Map<String,Object> context:就是一个Map,Context中主要存储了一些引用,这个引用主要是关于web开发中相关信息;
pameters :请求参数;
request:请求对象中全部属性;
session:会话对象中全部属性;
application:application对象中的全部发展;
在struts2框架中咱们经过ognl表达式来获取valueStack中数据,没有使用#就会从CompoundRoot中获取数据,若是使用#来获取,这时就会从context中来获取。
(1) 经过request对象来获取;
ValueStack vs = (ValueStack)ServletActionContext.getRequest()
.getAttribute(ServletActionContext.STURTS_VALUESTACK_KEY);
(2) 经过ActionContext来获取
ValueStack vs = ActionContext.getServletContext()getValueStack();
ActionContext它是action上下文,Strtus2框架它使用ActionContext来保存Action在执行过程当中所须要的一些对象,例如 session, application… ActionContext的获取 是经过它的静态方法getContext()获得。Struts2会根据每一次的http请求来建立对应的ActionContext,它是与当前线程绑定的。每一次请求,就是一个线程,对应着一个request,每一次请求,会建立一个Action,每个action对应一个ActionContext.每一次请求也对应着一个valueStack。它们都对应着一次请求(一个线程),valueStack与ActionContext本质上是能够获取。
(1) 手动向valueStack存储数据;
vs.push(String str); 和 vs.set(Object obj String str);
(2) Struts2框架自动向valueStack中存储数据;
每次请求,访问action,这个对象会存储到valueStack中。
在DefaultActionInvocation的init方法内,调用:vs.push(Action action);
在ModelDrivernInterceptor中,调用ModelDrivern的getModel()方法;
(1). Jsp页面获取,导入s标签库
<s:property value = “ “ />
(2). 在Action中属性
调用PO类getter方法;
(3). 在Model类中(即模型驱动)
调用getModel()方法;
El表达式能够从valueStack中获取信息,在jsp页面中显示:如:{$ model.name},org.apache.struts2.dispatcher.StrutsRequestWrapper这个类可使ValueStack使用EL表达式,Struts2框架对request进行了加强,重写了getAttribute方法,若是在request域中查找不到数据,就会在valueStack中获取。
OGNL是一般要结合Struts 2的标志一块儿使用。主要是#、%和$这三个符号的使用,#号:它是从非root中获取数据,%号用于强制是否要解析ognl表达式,$号主要是从配置文件中来获取valueStack中数据。
Struts2中的interceptor它是基于spring aop思想,而aop思想它本质上是经过动态代理来实现。咱们strtus2的拦截器它主要是拦截Action的操做,在action的执行前或执行后进行一些其它的功能操做。
拦截器链(拦截器栈)简单说,就是能够将多个拦截器造成一个链,在访问它们时依次访问。执行图见上图;
执行的过程:
当咱们发送请求访问Action时,会被StrutsPrepareAndExecuteFilter拦截在其doFilter方法内执行了execute.executeAction(request, response, mapping);这个代码执行后dispatcher.serviceAction(request, response, mapping);serviceAction方法执行在这个方法执行过程当中会建立Action代理对象ActionProxy proxy = getContainer().getInstance(ActionProxyFactory.class).createActionProxy( namespace, name, method, extraContext, true, false);经过proxy去执行了proxy.execute();在execute方法内return invocation.invoke();invocation它是ActionInvocation一个对象。会去加载咱们的配置文件,将配置文件中全部的interceptor获得进行遍历。在struts-default.xml文件中定义了默认加载的拦截器栈 defaultStack,在每个拦截器的interceptor方法内,又调用了DefaultActionInvocation的invoke方法,其实就是递归调用。
全部的Interceptor都要实现一个接口,在配置文件中声明Interceptor,能够将多个interceptor封装成一个stack,能够在Action的配置中引入本身的interceptor,在使用时name也能够引入一个interceptor stack。注意:当咱们显示的引入了一个自定义的Interceptor,那么默认的defaultStack就不会在导入,须要手动导入。
@Namespace来代替<package namespace=””>
@ParentPackage来代替<package extends=””>
@Action来描述关于<action>配置
value属性<action name=””>
使用@Action的results来描述关于结果类型的配置<result>
<result name=”” type=””>
@Action(results={@Result(name=””,type=””,location=””)})
@Actions
做用:能够经过多个映射来访问同一个action;
@Results
相似于全局的结果视图;
@InterceptorRef
它是用于处理拦截器的;