Struts2
概述:
使用框架可以提高代码的复用性,减少重复代码的编写。提高软件的生产效率和质量。因为框架已经提供了统一的开发标准和规范,所以使用框架开发后的产品,便于后期的维护。Struts2是基于MVC设计模式的web层框架。作为控制器来建立模型和视图之间的交互。相当于之前的servlet。
Struts2的三核心:拦截器(interceptor)、action、ognl和valueStack。
Struts2框架封装数据【重点】
主要解决的问题:是在action中如何获取请求参数????
1、Struts2如何接受前端传来的参数,如何封装这些参数????
主要有两种方式:
1.属性驱动
a、在具体的Action类中定义与前端name值一致的成员属性,并提供相应的set/get方法。
b.在action类中创始一个javaBean,对其提供get/set ,在请求时页面上要进行修改, 例如 user.username user.password,要使用ognl表达式
以上两种方式的优缺点:
第一种比较简单,在实际操作我们需要将action的属性再赋值给模型(javaBean) 去操作。
第二种:不需要再直接将值给javaBean过程,因为直接将数据封装到了javaBean 中。它要求在页面上必须使用ognl表达式,就存在页面不通用问题。
2.模型驱动
步骤:
1.让Action类要实现一个指定接口ModelDriven。
2.实例化模型对象(就是要new出来javaBean)。
3.重写getModel方法将实例化的模型返回。
示例代码:public class LoginActionextends ModelDriven {
private User user = new User();
@Override
public User getModel(){
return user;
}
}
对于模型驱动它与属性驱动对比,在实际开发中使用比较多,模型驱动缺点,它只能对一个模型数据进行封装。
3.可以再具体Action类中获取 Servlet API 再通过这些servlet的API 获取前端传来的参数,一般也不用这种方式。
简单说,可以在action类中获取request response session...对象
有两种方案:
1.通过ServletActionContext获取
这个对象有对应的获取servlet 的相应具体对象的一些setXXX()/getXXX() 的静态方法。
2.采用注入方式
Struts2框架在运行时,请求会被StrutsPrepareAndExecuteFilter拦截,会根据请求,去 strtus.xml文件中查找到匹配的action,在action执行前,会走一些interceptor。
默认执行的拦截器是struts-default.xml文件中定义的。
在默认执行的拦截器中有一个 servletConfig 拦截器。
查看一下ServletConfig拦截器的源代码发现,该拦截器会进行一系列的判断,这个具体的Action是否实现了某些特定的具体的接口,就会获取对应节后中的servlet 的一些具体对象,例如下边的一些接口。
ServletRequestAware, 实现这个接口可以获取HttpServletRequest
ServletResponseAware ,实现这个接口可以获取HttpServletResponse
ServletContextAware 实现这个接口可以获取ServletContext
Struts2如何完成的页面跳转????
我们可以给action中的方法添加一个String返回值,同时在struts.xml配置文件中,在其对应的<action>配置上通过<result>来确定跳转的路径。
Struts2简单大体执行流程
1.当通过浏览器发送一个请求
2.会被StrutsPrepareAndExecuteFilter拦截
3.会调用strtus2框架默认的拦截器(interceptor)完成部分功能
4.在执行Action中操作
5.根据Action中方法的执行结果来选择来跳转页面Resut视图
struts.xml文件配置介绍【应用】
1.package配置
1.name属性 作用:定义一个包的名称,它必须唯一。
2.namespace属性 作用:主要是与action标签的name属性联合使用来确定一个action 的访问路径
3.extends属性 作用:指定继承自哪个包。一般值是strtus-default
strtus-default包是在strtus-default.xml文件中声明的。
4.abstract属性 它代表当前包是一个抽象的,主要是用于被继承
2.action配置
1.name属性 作用:主要是与package的namespace联合使用来确定一个action的访问路径
2.class属性 作用:用于指示当前的action类的类全类名
3.method属性 作用:用于指示当前的action类中的哪个方法执行
3.result配置
它主要是用于指示结果视图
1.name属性 作用是与action类的method方法的返回值进行匹配,来确定跳转路径,默认“success”
2.type属性 作用是用于指定跳转方式 ,默认为 转发(dispacher)
4.扩展
关于action配置中的class与method的默认值以及result中的name与type 默认值问题
<action name="test">
<result>/success.jsp</result>
</action>
原因:strtus-default.xml文件中配置
<default-class-ref class="com.opensymphony.xwork2.ActionSupport">
它的作用就是当一个请求来时,如果查找不到指定的class及对应的method就会执行
ActionSupport类中的execute方法。
在这个类的execute方法中默认返回的是”success”
也就是说,result的name属性默认值是success,默认的跳转方式是请求转发 dispatcher
Struts2的Action详解
Struts2中的action,主要是完成业务逻辑操作。Action替代在servlet中完成的作用。
Action的学习主要有两点:
1.如何创建一个struts2的action????
Action类创建方式(三种)【理解】
1.创建一个pojo类
Pojo(plani Ordinary java object)简单的java对象
Pojo类就是没有实现任何接口没有继承任何类
优点:无耦合
缺点:所有的功能都要自己完成
2.创建一个类实现一个Action接口
com.opensymphony.xwork2.Action
在Action接口中定义了五个常量,一个execute()方法。
五个常量:它们是默认的五个结果视图<result name=””>:
ERROR : 错误视图
INPUT: 它是struts2框架中interceptor中发现问题后会访问的一个视图
LOGIN:它是一个登录视图,可以在权限操作中使用
NONE:它代表的是null,什么都不做(也不会做跳转操作)
SUCCESS:这是一个成功视图
execute(): String
优点:耦合度低
缺点:还是需要自己来完成功能
3.创建一个类继承ActionSupport类
com.opensymphony.xwork2.ActionSupport
ActionSupport类也实现了Action接口。
我们在开发中一般会使用这种方案:
优点:具有丰富的功能,例如 表单校验 错误信息设置 国际化
缺点:耦合度高
如何访问一个struts2的action
action的访问方式【重点】
1.直接通过<action>标签来配置,通过method来指定访问的方法,如果method没有,默认访问的是execute方法。
2.简化的action访问方式,可以使用 * 通配符来访问。(参考课件struts-day01中的图片)
这种方式的缺点:不建议使用过多的 * 号,它带来程序阅读障碍,不便于理解。
使用 * 来简化操作方案,它对名称规范必须进行一个统一。
3.扩展--动态方法调用
访问地址写法(注意 ! 感叹号):localhost:8080/struts_day01/struts2!show
这是strtus2提供的动态方法调用。
注意:对于strtus2的动态方法调用,要想使用我们必须配置一个常量来开启动态方法调用
struts.enable.DynamicMethodInvocation = false ------这代表动态方法调用没有开启
需要再struts.xml中配置这个常量为 true。
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
注:不建议使用动态方法调用!!!!
Struts2中获取Servlet API
(一) 在action类中获取request response session...对象
有两种方案:
1.ServletActionContext 静态方法
ServletActionContext.getRequest();
ServletActionContext.getResponse();
ServletActionContext.getServletContext();
2.采用注入方式,通过实现接口来获取servlet(拦截器)
Struts2框架在运行时,请求会被StrutsPrepareAndExecuteFilter拦截,会根据请求,
去strtus.xml文件中查找到匹配的action,在action执行前,会走一些interceptor
默认执行的拦截器是struts-default.xml文件中定义的。
在默认执行的拦截器中有一个
<interceptor-ref name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
ServletRequestAware, 实现这个接口可以获取HttpServletRequest
ServletResponseAware ,实现这个接口可以获取HttpServletResponse
ServletContextAware 实现这个接口可以获取ServletContext
二、OGNL表达式
概念:
OGNL是Object-Graph Navigation Language(对象图导航语言)的缩写,它是一种功能强大的表达式语言,通过它
简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它
使用相同的表达式去存取对象的属性。
OGNL三要素:
表达式: OgnlContext 上下文 Root 根
1.OGNL表达式的计算是围绕OGNL上下文进行的。
OGNL上下文实际上就是一个Map对象,由ognl.OgnlContext类表示。它里面可以存放很多个JavaBean对象。它有一个上下文根对象。
上下文中的根对象可以直接使用名来访问或直接使用它的属性名访问它的属性值。否则要加前缀“#key”。
2.Struts2的标签库都是使用OGNL表达式来访问ActionContext中的对象数据的。如:<s:propertyvalue="xxx"/>。
3.Struts2将ActionContext设置为OGNL上下文,并将值栈作为OGNL的根对象放置到ActionContext中。
4.值栈(ValueStack) :
可以在值栈中放入、删除、查询对象。访问值栈中的对象不用“#”。
Struts2总是把当前Action实例放置在栈顶。所以在OGNL中引用Action中的属性也可以省略“#”。
5.调用ActionContext的put(key,value)放入的数据,需要使用#访问
三、ValueStack
配合ognl使用,ognl主要是配合jsp来使用
ValueStack包括:
list----->ognl的根(获取这里面的值不需要加#) 注意:在根中保存了我们当前的action对象
map------>普通的数据(获取这里面的值需要加#)
ValueStack是如何进行保存数据的(栈结构)
手动存储
vs.push(Obejct)不用
vs.set(key,value) 用
自动保存
action对象
自动保存model(接收前台传过来的数据对象模型) 前提---实现modeldriven接口
ValueStack是如何取值
在jsp页面使用struts标签进行取值
四、Interceptor拦截器
(一) Interceptor简介
(二) 自定义Interceptor
自定义的Interceptor
1.创建一个类继承或者实现 Interceptor接口(匹配访问当前action的所有方法) MethodFilterInterceptor(匹配指定方法)
2.实现doIntercept()方法
in....invoke();代表放行当前action进入下个Interceptor
不执行invoke()代表拦截该action,就会通过该方法的返回值跳转指定页面
3.在struts.xml中配置拦截器
在action配置具体拦截器/引入自定义的拦截器还需要导入默认的拦截器!!!
五:Struts2的工作流程:
1.客户端在浏览器中输入一个url地址;
2.这个url请求通过http协议发送给tomcat;
3.tomcat根据url找到对应项目里面的web.xml文件;
4.在web.xml里面会发现有struts2的配置;
5.然后会找到struts2对应的struts.xml配置文件;
6.根据url解析struts.xml配置文件就会找到对应的class;
7.调用完class返回一个结果result,根据struts.xml返回到对应的jsp;