1, Struts2应用的分层体系结构
具体例子!!!
2, Struts2的模型驱动(Model Driven),之前我们使用的都是属性驱动(Property Driven)
3, 属性驱动与模型驱动的比较:
1) 属性驱动灵活,准确;模型驱动不灵活,因为很多时候页面提交过来的参数并不属于模型中的属性,也就是说页面所提交过来的参数与模型中的属性并不一致,这是很常见的情况。
2) 模型驱动更加符合面向对象的风格,使得我们获得的是对象而不是一个个离散的值。
推荐:使用属性驱动编写Action。
4, Struts2允许我们在Action中操作request,response,session等一系列的Servlet API。这里介绍一种最简单的方式。
页面获取session
5, Preparable接口作用是让Action完成一些初始化工作,初始化工作放在Preparable接口的prepare()方法中完成的。
6, struts.xml中result元素默认情况下是以请求转发(dispatcher)的形式,跳转到结果页面。result元素的type属性取值可以到struts-default.xml文件中查到。结果类型redirectAction的重要性仅次于dispatcher。
7, 采取请求转发的方式完成表单内容的添加会造成内容的重复插入。
8, 采取重定向的方式实现数据的添加不会造成数据的重复插入。
9, redirectAction的使用例子
10, chain是action之间的请求转发,因此是在一个请求中完成的。
11, 防止表单重复提交的两种方式:
1) 通过重定向
2) 通过Session Token(Session令牌):当客户端请求页面时,服务器会通过Token标签生成一个随机数,并且将该随机数放到session中,然后将该随机数发向客户端;如果客户第一次提交,那么会将该随机数发往服务器端,服务器会接收到该随机数并且与session中所保存的随机数进行比较,这时两者的值是相同的,服务器认为是第一次提交,并且更新服务器端那个随机值;如果此时再次重复提交,那么客户端发向服务器端的随机数还是之前的那个,而服务器端的随机数已经发生了变化,两者不同,服务器认为是重复提交,进而转向invalid.token所指向的结果页面。
12, 使用Struts2 Token机制时,表单必须用Struts2的标签库写表单。
13, 拦截器(interceptor):拦截器是struts2的核心,struts2的众多功能是通过拦截器实现的。拦截器类似于Servlet中的过滤器。拦截器是单实例。拦截器是无状态的(成员变量不可更改)
14, 拦截器的配置:
1) 编写实现Interceptor接口的类;
2) 在struts.xml中定义拦截器;
3) 在action中使用拦截器。
struts.xml中定义拦截器:
<interceptors>
<interceptor name="first" class=""><interceptor/>
<interceptor name="" class=""><interceptor/>
<interceptor name="" class=""><interceptor/>
<interceptor name="" class=""><interceptor/>
<interceptor name="" class=""><interceptor/>
</interceptors>
在action中使用拦截器
<action>
<interceptor-ref name="first"></interceptor-ref>
</action>
15, 一旦定义了自己的拦截器,将其配置到action上后,我们需要在action的最后加上默认的拦截器栈:defaultStack。
<interceptor-ref name="defaultStack"></interceptor-ref>
16, 对于拦截器,方法init(),destroy()通常是不需要的。定义拦截器时可以直接继承抽象类AbstractInterceptor(该类实现了Interceptor接口,并对init和destroy方法进行了空实现),然后实现其抽象方法intercept。
实现顺序:拦截器实例化-----拦截器成员变量set()参数-----init----intercept()----invoke,调用下一个拦截器,如果没有下一个拦截器,开始调用action------action成员变量set()-------validate()---execute-----拦截器一直return到第一个拦截器,调用结果(success,input等)
注:如果拦截器拦截时,调用return Action.LOGIN或Action.SUCCESS等方法时,直接取struts.xml中的结果执行。
<global-results>
<result name="login">/index.jsp</result>
<result name="success">/index.jsp</result>
.......................................
</global-results>
17, 方法过滤拦截器(可以对指定方法进行拦截的拦截器)。抽象类MethodFilterInterceptor类是抽象类AbstractInterceptor的子类,要给它指定要对那个方法进行过滤,可以设置的参数有excludeMethods(从拦截器中要排除的方法,即不过滤的方法),includeMethods(在拦截器中要被包含的方法,即要进行过滤的方法),如果一个方法既在excludeMethods中出现,又在includeMethods中出现,struts2认为它是includeMethods的。如果既没有指定includeMethods参数,也没有指定excludeMethods参数,那么所有方法都会被拦截。
invocation.addpreresultlistener(preresultlistener pre)的执行顺序在action的execute之后,拦截器返回result结果之前
18, 拦截器的一个应用场景,检查是否登录
19, 我们可以定义struts1.xml,struts2.xml将struts.xml分散开来,然后在主struts.xml中使用<includefile="struts1"></include>的形式将它们包含过来。
20, struts.xml中package元素的abstract属性表示该包是抽象的,不能直接使用,需要由子包继承使用。struts-default.xml这个package就是abstract的,因此需要我们继承这个包使用。
21, struts.xml中package元素的namespace属性,启到路径分割的作用。它是一个路径,相对于ContentPath来说的,必须以“/”开头,namespace的名字与package的name属性没有任何关系。通常我们将namespace的属性值定义成页面所在的目录名。