什么是Struts2 ?
Struts2是一款优秀的mvc框架 Struts2是由传统的Struts1和webwork 两个经典的mvc框架发展而来,与sturts1相比 允许使用javabean作位Action ,可以与Servlet Api 进行解耦合 更加容易测试 支持视图技术 基于Aop思想的拦截机制 提供了很好的扩展性
2、MVC:
是一种思想,是一种模式,将软件分为 Model模型、View视图、Controller控制器struts2 就是 web层开发框架,符合MVC模式
* struts1 、webwork 、jsf 、SpringMVC 都是MVC
它是面向对象程序设计语言应该遵守的规范
MVC的特性:
** 多个 视图视图对应一个模型
** 模型返回的诗句 与显示 逻辑分离
** 应用层分为三层 降低了各层之间的耦合性 提高了可扩展性
** 控制层把不同的视图组合在一起 完成不同的请求 在当前请求层中包含了用户的权限
** mvc 更符合软件工程化的管理精神 各层负责不同的工作 每一层的组件有相同的特性 有利于通过工程化和工具产生程序代码
JavaEE软件开发三层架构 web层(表现层) 业务逻辑层 数据持久层
3、 Struts2 和 Struts1 关系
没有关系, Struts2 全新框架,引入WebWork很多技术和思想,Struts2 保留Struts1 类似开发流程
* Struts2 内核 webwork
Xwork提供了很多核心功能:前端拦截机(interceptor),运行时表单属性验证,类型转换,强大的表达式语言(OGNL – the Object Graph Navigation Language),IoC(Inversion of Control反转控制)容器等
MVC:struts2,struts1,webwork,jsf,spring mvc
Struts2对视图的支持,jsp(el,jstl,ognl),freemarker,velocity
struts2 运行流程分析
1、 运行流程 org.apache.struts2.dispatcher.ng.filter包
请求 ---- StrutsPrepareAndExecuteFilter 核心控制器(预处理 执行过滤) ----- Interceptors 拦截器(实现代码功能 ) ----- Action 的execute --- 结果页面 Result
* 拦截器 在 struts-default.xml定义
* 执行拦截器 是 defaultStack 中引用拦截器
Acton创建的三种方式:
1.创建普通的pojo类(public String execute())
2.实现Action接口 (implements Action)Action接口定义默认的几种结果集(input,success,error,login,none)
3.继承ActionSupport类 (开发最常用的方式)
页面向Action传递参数的传递方式
1.属性的映射
页面上:编写input 表单的 name属性 <input type=”text” name=”userName” />
Action 定义和input表单的name属性一致,get,set方法 private String userName; 省略get,set方法
2.实体的映射(映射多个实体)
页面上:编写input 表单的 name属性 <input type=”text” name=”user.userName” />
Action 定义和input表单的name属性一致,get,set方法 private User user; 省略get,set方法
3.(实体)模型驱动(继承ActijonSupport类,modelDriver),只能映射一个实体
页面上:编写input 表单的 name属性 <input type=”text” name=”user.userName” />
Action:定义实体必须进行初始化;private User user=new User();
实现 public User getModel(){}
Action的配置
默认在 src下名称叫,struts-default.xml,或strut-plugin.xml或struts.xml(最常用)
属性:
<action name=”login_*” class=”” method=”{1}” /> method:省略不写时,默认的方法 public String execute(){}
页面视图映射 请求方式:四种:dispatcher(默认),redirect(对应的视图)
<result name=”success” >/success.jsp</result>
chain,redirectAction(对应的是action)
<result>
<param name=”namespace”>/test1</param>
<param name=”actionName”>login</param>
</result>
Action的主要作用有三个:
封装客户端请求数据
处理业务
返回结果
常量的配置:所有struts2的常量的配置在struts2-core的struts.properties
<!--项目编码 -->
相当于:request.setCharcterEncoding(“utf-8”);
<constant name=”struts.i18n.encoding” value=”UTF-8” />
<!--配置请求的后缀名称: 多个后缀名用逗号隔开 默认的后缀:.action,后缀名可以省略不写-->
struts.action.extension=action,,
<constant name=”struts.action.extension” value=”do,go,action” />
<!--服务器端的静态内存是否进行浏览器缓存 在开发模式下值设为false,产品(运行)环境下设为true-->
struts.serve.static.browserCache=true
<!-- 支持动态方法调用 -->
struts.enable.DynamicMethodInvocation =true
struts.action.extension=action,, 默认以.action结尾扩展名 和 不写扩展名 都会分发给 Action
<constant name="struts.serve.static.browserCache" value="false"/> false不缓存,true浏览器会缓存静态内容,产品环境设置true、开发环境设置false
<!-- 提供详细报错页面,修改struts.xml后不需要重启服务器 (要求)-->
<constant name="struts.devMode" value="true" />
1.导入jar包: struts2-core
Commons-lang
Commons-io
Commons-fileupload
Ognl
Free-marker
X-work
Javassist
2.创建一个login.jsp页面
3.编写Action,普通的类,重写public String execute()
4.编写Action的xml文件,默认struts2 找src下struts.xml或struts-default.xml
<action name=”请求的名称” class=”对应的Action类”>
<!--返回结果和视图的映射关系 -->
<result name=”action返回字符串1”>视图名称1</result>
<result name=”action返回字符串2”>视图名称1</result>
<result name=”action返回字符串3”>视图名称1</result>
</action>
Struts2支持使用多种视图技术,例如JSP、Velocity和FreeMarker等
当一个Action处理用户请求结束后,仅仅返回一个字符串,这个字符串就是逻辑视图名
在配置result时,name属性可以省略的如果省略,Struts2会默认name值为”success”
type属性决定了配置result的结果类型,如果省略,默认dispatcher
(转发)结果类型
Struts2支持的转发类型: 默认转发的类型:dispatch
配置:<result name=”success” type=”dispatcher/redirect/redirectAction/chanin”></result>
dispatcher 相当于request.getRequetDispatcher().forward() 服务器内部的转发
转发后页面(request.getParameter(“user.userName”))和action共享请求数据
redirect 相当于response.sendRediret(); 转发后的页面,不能获取action的参数,
redirectAction 客户端转发到action,地址是转发后的action地址,两个action参数不共享
chain 服务器内部,转发到下一个action ,地址栏是前一个action的地址,参数共享
在struts2中,从一个包(package)的action访问另一个包中的action,二者在不同的namespace中时,需要在struts的配置文件中作如下配置
· <result name="success" type="redirectAction">
·
· <param name="namespace">/other</param>
·
· <param name="actionName">view</param> actionName和要转发的action的name保持一致,不需要加后缀名
·
· </result>
·
Action是放在package下面,package不能重名,namespace不能重名
package的属性:
name:只是用来管理action;同一包下的action不能同名,如果同名后覆盖前
extends:所有的包都必须继承默认包: 默认包: struts-default
namepsace(/namespaceName)和action的Name:决定
action的访问路径 项目路径/namespaceName/actionName
web.xml配置过滤器
<!-- org.apache.filter.dispatcher.gn.filter.StrutsPreparedAndExecuteFilter -->
Struts2对action访问通过package 的namespace的方式进行管理
添加namespace属性以后:对action的访问: namespace/actionName
Struts2默认加载src目录下的struts-default.xml.struts-plugin.xml,struts.xml
Struts配置文件的分离:
Struts.xml引入相关配置文件
<include file=””/>
Action获取页面的参数的方式:
1.编写input表单对应的name 属性,get,set方法
2.在页面上input表单的name以对象.属性名,在action把对象作为action的属性,并给予public get,set方法
struts2不要求自定义的action类继承任何的struts基类或struts接口
为了简化Acion的开发,大多数情况下都会继承com.opensymphony.xwork2.ActionSupport类
ActionSupport类是一个工具类,实现了Action和Validateable接口,提供了数据校验功能、文件上传、token验证等功能。
Action的创建方式
1.编写纯净的pojo类,默认加载public String execute()
2.实现Action接口
3.继承ActionSupport(最常用的一种)
Struts2动态方法的调用 :
1.编写action继承ActionSupport (SUCEESS,INPUT,ERROR,)
2.编写方法
3.Action调用方式:action名称!方法名.后缀名
但DMI可能带来安全隐患,可以在struts.xml中配置常量元素来禁止使用:
<constant name="struts.enable.DynamicMethodInvocation" value=“false"/>
Struts2的通配符:
Action的配置方式: <action name=”login_*” class=”com.yh.action.LoginAction” method={1}></action>
Login_check.do 进入check方法
Login_handle.do 进入handle方法
创建自定义的拦截器
拦截器实现原理:动态代理
自定义的拦截器类,应该实现com.opensymphony.xwork2.interceptor.Interceptor接口
Incercept(Actionlnvocation invocation)
两个核心的方法 getAction() 获得与拦截器关联的Action,注意进行强制类型转换。
Invoke() 继续执行后面的拦截器或Action,可能抛出任何异常。
AbstractInterceptor实现Incercept接口,只需要继承AbstractInterceptor
拦截器的配置:
配置拦截器在package下
<interceptors>
<interceptor name="自定义拦截器名称" class="包名.拦截器类名"></interceptor>
</interceptors>
引用拦截器在Action内
<action>
//配置struts2默认的拦截器
<interceptor-ref name=”defaultStatck”></interceptor-ref>
//自定义的拦截器名称 一旦配置了自定义的拦截器,默认的拦截器不再执行 (引用下默认的拦截器defaultStatck)
<interceptor-ref name=”拦截器名称”></interceptor-ref>
</action>
2.引用方式
将多个拦截器放在拦截器栈,引用拦截器栈
<interceptors>
<interceptor name="自定义拦截器名称" class="包名.拦截器类名"/>
<interceptor-statck name=“perstack”>
<interceptor-ref name=”defaultStatck”></interceptor-ref>
<interceptor-ref name=”拦截器名称”></interceptor-ref>
</interceptor-statck>
</interceptors>
<action>
<interceptor-ref name=”perstack”></interceptor-ref>
</action>
配置默认的拦截器
<!-- 默认的拦截器 该包下所有的action不需要配置拦截器,也会被该默认的拦截器(栈)拦截 -->
<default-interceptor-ref name="permission"></default-interceptor-ref>
通过对struts2的学习,对于interceptor中的excludeMethods与includeMethods的理解:
针对MethodFilterInterceptor:
excludeMethods表示排除指定的方法,即不对标记为excludeMethods的方法进行拦截,
includeMethods表示包含指定的方法,即对标记为includeMethods的方法进行拦截,(优先级高于excludeMethods)
在struts.xml中关于excludeMethods和includeMethods有两种实现方式,一种相当于全局,另一种相当于局部,即
<interceptors>
<interceptor name="myInterceptor" class="com.interceptor.MethodInterceptor">
<param name="includeMethods">method1,method2</param>
</interceptor>
</interceptors>
声明的时候配置为全局。而引用的时候配置
<interceptor-ref name="myInterceptor">
<param name="excludeMethods">method1,method2</param>
</interceptor-ref>
为局部,
若全局中的param定义为excludeMethods同样局部中的param也定义为excludeMethods,则局部中的param生效,全局中的param无效,即被局部中的param覆盖,同样,若全局中的param定义为includeMethods同样局部中的param也定义为includeMethods,则局部中的param生效,全局中的param无效,即被局部中的param覆盖。
当全局中的param与局部中的param不相同的时,即当全局中param为excludeMethods而局部中的param为includeMethods或全局中的param为includeMethods而局部中param为excludeMethods,则标志为includeMethods生效。即若是全局中的param定义为includeMethods,则全局屏蔽局部,以全局为准,反之,若局部的param定义为includeMethods,则以局部为准。
如果即没有指定includeMethods也没有指定excludeMethods的方法默认的是includeMethods方法
如果仅仅指定了includeMethods的方法,没有包含在includeMethods里的方法就不会被拦截。
要实现自定义拦截器,需要继承MethodFilterInterceptor类。MethodFilterInterceptor类是AbstractInterceptor的子类