struts2总结
Struts2
struts的作用就是把视图和请求分开.
1. namespace:决定了action的访问路径,默认为"/",可以接收所有的action
也可以写成/xxx
2. 配置开发模式,改代码不用重启服务器
<constant name=”struts.devMode” value=”true”>
3. package 包组织,用于分块,区分同名的action
Package名一般和namespace名字相同
4. action 具体的视图可以由用户自定定义的Action来定义
具体的手段可以根据反回字符串对应的配置项,来决定视图的内容
具体的Action实现可以是一个普通的Java类,里面由public String execute()方法
一般是从ActionSupport继承,里面封装了许多方法.
5. struts2中通配符的用法
配置默认Action,如果没有此action,显示的内容
<default-action-ref name=”defaultAction”></default-action-ref>
<action name=”defaultAction”>/error.jsp</action>
6. struts2接收参数的三种方式
①通过action类的set/get方法赋值给成员变量来接收参数
②DomainModel使用预模型的方式,创建一个模型类,接收各种参数,然后在action类中将 此类的对象添加为成员变量,并设置set/get方法.
③ModelDriven模型驱动:实现ModelDriven<模型类对象>接口
7. 配置struts.xml文件的常量解决中文乱码问题:
<constant name=”struts.i18n.encoding” value=”utf-8”>
<!-- 配置.do,.action的请求方式 -->
<constant name="struts.action.extension" value="do,action"></constant>
8. struts2的简单数据校验
1. struts2过滤器拦截所有的请求,将不同的请求指向不同的类,调用不同的方法.
2. Struts2的基本执行过程:接收请求-->过滤器-->过滤器获取路径值-->到src下面找 struts.xml文件,使用dom4j解析xml文件找到action标签,匹配name属性值是否一 样-->匹配完name属性值一样后,找到action里面的action类的全路径,利用反射来 实现功能.
3. ****反射代码:
① 第一步:得到Class:Class class=Class.froName(“action的全路径”);
② 第二步:得到execute方法:Method m=class.getMethod(“execute”);
③ 第三步:方法执行:Object obj=m.invoke();得到返回值
④ 第四步:得到返回值后,匹配result的name值,进行页面的跳转.
4. struts2过滤器的源代码分析
过滤器随着服务器的启动而创建.
1. 在init方法中加载主要的配置文件,包含自己配置的配置文件和struts本身自带 的配置文件.
5. struts核心配置文件--struts.xml
①package标签:
1. 类似于包代码中的包,区别不同的action
2. Name属性:在一个配置文件中可以写多个package,但是每个package的 name属性值不能相同.
3. Extends属性:
属性值是固定的struts-default
表示在package里面配置的类具有action的功能.
4. Namespace属性:
Namespace属性值和action标签里面的name属性值构成访问路径
②action标签
1. name属性
Namespace属性值和action标签里面的name属性值构成访问路径
在package标签中可以写很多action标签,但是名字不能相同
2. Class属性:
Action的全路径
3. Method属性:
配置要是使用的方法
③result标签:
根据action的方法返回值,配置到不同的路径里面
1. name属性:方法的返回值
2. Type属性:配置如何到路径中(转发,重定向,默认为转发)
④constant常量:
<constant name=”struts.i18n.encoding” value=”utf-8”></constant>
6.struts分模块开发
1.单独写配置文件,然后把配置文件引入到核心配置文件中
<include file=”cn/yuntu/action/hello.xml”></include>
7.action的三种编写方式:
1.创建普通的Action类
2.创建action类实现Action接口 3.创建Action类继承ActionSupport
8.Action中方法的访问---通配符
在action的标签里面name属性写*号.表示可以匹配任意的内容
9. 在action中获取表单提交数据
结果页面配置:
1. 全局结果界面:如果多个页面返回值相同,并且到达的页面也相同
<!--全局结果页面的配置-->
只适应于当前包.
<global-results>
<result name=”success”>/hello.jsp</result>
</global-results>
2.局部结果界面:一般的配置result,既配置了全局结果页面,又配置了局部结果页面,
以局部界面为准.
10. result标签中的type属性
配置到页面的方式
1.默认为转发.dispatcher(地址不变,发生在服务器端)
2.重定向:redirect(地址发生改变,发生在客户端,数据会发生丢失)
3.配置到其他的action:--chain(一般不用,缓存问题)---/----redirectAction---
<!--result里面写的是重定向其他action的访问路径-->
**<result name=”success” type=”redirectAction”>orders.action</result>
11. 在action中获取表单数据的方式:
1. 使用ActionContext类
2. 使用servletActionContext类
3. 使用接口注入的方式
①使用ActionContext类的方式:----
//创建ActionContext类的对象
ActionContext context=ActionContext.getContext();
//调用方法获取表单数据
//key是表单里面的name值,value是输入的值
Map<String,Object> maps=context.getParameters();
//集合的遍历
Set<String> keys=maps.KeySet();
for (String key : keys){
//根据key 得到value,value是数组结构(复选框)
Object[] obj=(Object[]) maps.get(key);
System.out.println(Arrays.toString(obj));
}
②使用ServletActionContext类获取表单数据
//获取request对象
HttpServletRequest request=ServletActionContext.getRequest();
//调用方法获取参数
String username=request.getParameters(“username”);
③接口注入的方式
实现接口:ServletRequestAware
12. 在action中操作域对象
Request,session,servletContext
①request域
HttpServleteRequest request=ServletActionContext.getRequest();
Request.setAttrubute(“”,””);
②session域
HttpSession session=session.getSession();
session.setAttrubute(“”,””);
③servletContext域
ServletContext context =ServletActionContxt.getServletContext();
context.setAttrubute(“”,””);
13. 获取表单数据封装的方式
①属性封装:
在action中定义变量,变量名与表单属性的name值相同.
生成set/get的方法.
②模型驱动:使用模型驱动的时候一定要new一个实体
使用模型驱动的好处:吧参数封装到对象中.
第一步:让action实现接口ModelDriven
第二步:实现接口里面的方法getModel(),返回对象
第三步:在action里面创建实体类的对象.
注意:表单中的name属性值必须和实体类的属性值一样.
不能同时使用属性封装和模型驱动获取同一个表单的数据
如果同时使用只会使用模型驱动.
③表达式封装:
使用表达式封装的步骤
第一步 面写表达式形式
即在表单中的name属性中写对象.属性名即可.
*****比较表达式封装和模型驱动封装
*相同点:使用表达式封装和模型驱动封装都可以吧参数封装到对象中
但是模型驱动封装不能把数据封装到另一个实体类中.
*表达式封装可以把数据封装到不同的实体类对象中.
14. 获取数据封装到集合中
① 封装数据到list中
跟表达式封装差不多
第一步:声明list集合
Private List<User> list;
第二步:提供set/get方法
第三步:在表单中写表达式
② 封装数据到map集合中
声明Map集合
Private Map<String,User> map;
15. ognl---对比EL表达式,EL表达式在jsp中获取域对象的值
OGNL全称对象图导航语言object-Graph Navigation language
在struts2中操作值栈的数据.和struts2的标签结合使用操作值栈数据
使用OGNL需要导入jia包.然后引入s标签.
16. 什么是值栈
1.之前在servlet里面进行操作,吧数据放到域对象,在页面使用EL表达式获取
2.在struts2里面提供了一种存储机制,类似于域对象,是值栈
(1)在action里面可以把数据放在值栈里面,在页面获取值栈数据
3.值栈存储的位置
(1)servlet和action的区别
Servlet:在第一次访问时创建.创建一次,单实例对象
Action:在访问时创建,每次访问action的时候都会成创建action对象,多实例对
(2) 值栈的存储位置
每次访问时都会创建action对象
在每个action对象里面都只有一个值栈对象
4. 获取值栈对象
1. 获取值栈对象有多种方式
(1) 使用ActionContext类里面的方法获取值栈对象
//获取ActionContext对象
ActionContext context=ActionContext.getContext();
//获取值栈对象
ValueStack stack=context.getValueStack();
5. 值栈的内部结构
值栈:栈:是一种数据结构.先进后出.后进先出,最上面的叫做栈顶元素
值栈主要分为两部分:
1. Root
结构是list集合
2. Context
结构是Map集合
存储的是对象的引用
key是固定的,主要有request,session,application,parameters,attr
Value是对象的引用
当action没有任何操作的时候,栈顶元素就是这个action的引用
Action对象里面有值栈对象,值栈对象里面有action的引用
17. 向值栈放数据的三种方式
第一种: 获取值栈对象,调用里面的set方法
分配一个Map集合的空间
//获取值栈对象
ValueStack stack=ActionContext.getContext.getValueStack();
//调用set方法
stack.set(“username”,”哈哈”);
第二种: 获取值栈对象,调用里面的push方法
分配一个Object的空间.
//获取值栈对象
ValueStack stack=ActionContext.getContext.getValueSta
//stack.push(“abck”);
第三种: 在action定义变量,生成变量的get方法,常用
好处:数据直接存储在action里面,减少空间的分配
//定义变量
Private String name;
//生成get方法
Public String getName(){
Return name;
}
//在执行的方法中设置值
Public String execute(){
Name=”哈哈”;
Return SUCCESS;
}
18. 向值栈放对象
第一步: 定义对象为成员变量
Private User user=new User();
第二步: 生成变量的get方法
Public User getUser(){
}
第三步: 在具体的action的方法里面向对象里面设置值
User.set.......
向值栈放list对象
//应用:查询所有的时候
第一步: 定义list集合的变量
Private List<User> list=new ArrayList<User>();
第二步: 生成变量的get方法
Public List<User> getList(){
Return list;
}
第三步: 在执行的方法里面向list集合设置值
List.add(user);
19. 向值栈中获取数据
使用struts2的标签和ognl表达式来获取值栈数据
①获取字符串
<s:property value=”username”>
②获取对象
<s:property value=”user.username”>
<s:property value=”user.password”>
<s:property value=”user.address”>
③获取list集合
第一种方式:
<s:property value=”list[0].username>
第二种方式:
<s:iterator>遍历值栈的list集合
<s:iterator value=”list集合” >
<s:property value=”username”>
<s:property value=”password”>
<s:property value=”address”>
</s:iterator>
第三种方式:
<s:iterator value=”list集合” var=”对象名user” >
//为了取值更快,把每次遍历出来的对象
//放到Context里面,份配一个空间,key代表对象
//value代表对象的引用,使用特殊的符号来取
//取context里面的数据需要加上#号来取
//设计的好处:效率更高
<s:property value=”#user.username”>
<s:property value=”#user.password”>
<s:property value=”#user.address”>
</s:iterator>
20. 获取set和push方法设置的值
1. 获取set方法设置的值,根据名称获取值
<s:property value=”值栈set的key”>
2. 获取push方法设置的值,没有名称,只有设置的值
向值栈中放入数据,会存储到数组里面,数组名称叫做top.
<s:property value=”[0].top”>//表示取数组中的第一个值,即栈顶的值
21. EL表达式获取值栈数据
使用foreach标签和EL表达式获取值栈数据
<c:foreach items=”${list }” var=”user”>
${user.username}
</c:foreach>
为什么可以获取?
EL表达式获取域对象的值,
底层增强request里面的getAttribute方法
1. 首先从request域获取值,如果获取到,直接返回
2. 如果从request域获取不到值,到值栈中把值取出来
把值放到域对象里面.
所以EL表达式取得还是域对象里面的值,性能较低!
22. OGNL中#的使用
使用#号获取值栈中context里面的值
Context中的key是固定的
示例:
1. 向request中设置值
//获取context中的数据,写OGNL表达式的时候
//首先先添加符号,#
//然后是key的名字
//key是固定的request,session,application,parameters,attr
2. <s:property value=”#request.username”>
23. OGNL中%的使用
***%的使用在struts2标签里面使用ognl表达式
如果直接在struts2表单里面直接使用ognl表达式
不识别,加上%就可以了.
举例子:
<s:textfield name=”username” value=”%{#request.username}”></s:textfield>
24. struts2拦截器
1.Struts2是框架,封装了很多功能,都在拦截器里面
2.Struts2里面封装了很多功能,有很多拦截器,不是每次这些拦截器
都执行,每次执行默认的拦截器.
3.拦截器在action对象创建之后,action中的方法执行之前执行.
25. 拦截器的底层原理(aop思想)
1. 拦截器的底层主要有两个原理
(1) aop思想
面向切面(方面)编程
有基本的功能,扩展功能,不通过修改源代码的方式扩展功能
(2) 责任链模式
*责任链模式是Java中的一个模式
*责任链和过滤链很相似,一个请求可以有很多个过滤器进行过滤,放行后才可 以到下一个
在action里面并没有直接调用拦截器的方法,使用配置文件的方式.
在执行拦截器的时候,执行很多的拦截器,这个过程使用责任链模式.
拦截器的执行过程:....
26. 过滤器与拦截器的区别
过滤器与拦截器的区别:
过滤器:服务器启动创建,可以过滤所有的内容
拦截器:拦截action
Servlet与action的区别:
Servlet:默认第一次访问的时候创建,创建一次,单实例对象
Action:每次访问的时候创建,创建多次,多实例对象.
27. 自定义拦截器
1.在struts2里面有很多拦截器,但是在实际的开发中需要自定义拦截器
来增强我们的功能.
2. 拦截器的结构
继承了一个类AbstractInterceptor
AbstractInterceptor实现了接口Interceptor
接口中有三个方法:init(),destroty(),String intercept(ActionInvocation invocation)
**在开发中用另一种方式
写一个类继承一个类,MethodFilterInterceptor
可以让action中某些方法不进行拦截.
3. 让拦截器和action有关系
不是在action中调用方法,而是通过配置文件的方式建立联系
28. 拦截器的实现过程
1. 写一个类,继承MethodFilterInterceptor
2. 重写继承的类里面的方法写拦截的逻辑步骤
3. 配置action与拦截器的关系(注册拦截器)
(1) 再要拦截的action标签所在的package里面声明拦截器
(2) 在具体的action标签里面来使用声明的拦截器
(3) Struts里面执行很多默认的拦截器,配置了自定义拦截器
默认的拦截器就不执行了.
把默认的拦截器在手动进行配置
<interceptor-ref name=”defaultStack”></interceptor-ref>
29. 自定义拦截器拦截不需要的方法
配置完自定义拦截器会拦截action的所有的方法
会导致一直登陆不上.此时可以配置login方法不用拦截
***不登陆状态,经过拦截器之后再次进行登陆时,会出现页面重叠的错误
设置:
在登录界面的form标签里面设置target=”_parent”
30. struts2的标签
<s:property value=””/>
<s:iterator></s:iterator>
<s:debug></s:debug>
<s:if></s:if>
struts2表单标签
31. struts2核心架构分析图