Struts2 Lesson2
1. Struts2的类型转换,对于8个原生数据类型以及Date,String等常见类型,Struts2可以使用内建的类型转换器实现自动的转换;但对于自定义的对象来说,就需要我们自己制定
类型转换的方式了。
2. 对于自定义类型转换器来说需要提供3个信息:Action的名字、Action中待转换的属性名以及该属性对应的类型转换器。其中Action的名字是通过属性文件名来获得的、Action中
待转换的属性名是通过属性文件中的key来获得的,该属性对应的类型转换器是通过该key所对应的value来获得的。
3. 可以使用Struts2框架自带的类型转换器StrutsTypeConverter简化类型转换代码的编写,StrutsTypeConverter继承于DefaultTypeConverter父类,并且提供了两个抽象方法:
convertFromString与convertToString,分别表示从页面的字符串转换为后台对象以及从后台对象转换为页面的字符串,我们只需实现这两个抽象方法即可实现类型转换。
4. 全局类型转换。在src目录下新建xwork-conversion.properties,该文件的内容是待转换的类=转换器的名字,即
<com.shengsiyuan.bean.User=com.shengsiyuan.converter.UserConverter2>
5. Struts也支持自定义方法,即在struts.xml中的action元素内定义method属性,属性值即为待执行的方法。其中,该方法的声明要与execute保持一致。
但是不推荐使用这种方式,因为它容易导致Action中代码混乱。
6.执行的流程:
首先进行类型的转换
然后进行输入校验(执行validate方法)
如果在上述过程中出现了任何错误,都不会再执行execute方法,会转向struts.xml中该action的名为input的result所对应的页面。
7. ActionSupport类的addActionError()方法的实现:首先创建一个ArrayList对象,然后将错去的消息添加到ArrayList对象中。
8. 当调用getActionError()方法返回Action级别的错误信息列表时,返回的实际上是集合的一个副本而不是集合本身,因此
对集合副本调用clear()方法清除的依旧是副本中的元素而非原集合中的元素,此时原集合中的内容没有受到任何的影响。
<换句话说,Action级别的错误信息列表对开发者来说是只读的。>
9. Field Error 级别的错误信息底层是用LinkedHashMap实现的,该Map的key是String类型的,value是List<String>类型,这就表示一个
Field Name 可以对应多条错误信息,这些错误信息都放置在List<String>集合当中。
Struts2 Lesson3
1. Action中自定义方法的输入校验,对于通过action的method属性所指定的自定义方法,其对应的自定义输入校验方法名为validateMyExecute(假设自定义的方法名为myExecute)。
底层是通过反射来调用的。
2. 当在Action中指定了自定义的execute方法时,首先会执行自定义的execute方法所对应的输入校验方法,然后再去执行validate方法,执行完毕后
如果出现了任何错误都不会再去执行自定义的execute方法,流向转向了input这个名字所对应的页面上。
3. 自定义Field级别的错误提示消息
1---> 新建一个以Action名命得properties文件,如RegisterAction.properties。
2---> 然后在该属性文件中指定每一个出错字段的错误消息invalid。fieldvalue.brithday=brithday invalid!!!
4. Struts2的校验框架(有效的xml文件)。具体来说分为字段优先校验器与校验器优先校验器。
5. 对于国际化的资源文件,其命名规则是:package_语言名_国家名,比如< 中国package_zh_CN, 美国package_en_US >.
6. Struts2框架校验执行的先后顺序:<以下三个校验之前先执行的是类型转换>
1--> 首先执行校验框架(xml文件)
2--> 执行自定义方法的校验方法(vaildateMyExecute)
3--> 执行validate方法
7. 对于Struts.xml文件的结果配置来说,局部要优于全局。
8. 我们既可以在Action中定义异常与结果,也可以定义全局的异常与结果,局部总是优于全局的,如果定义成全局,那么可以为所有的Action所公用,而局部的异常与结果只能被
当前的Action所独享,不能够为其他的Action所共享。
Struts2 Lesson4
1. Struts2 应用的分层体系架构 (Action)<---(Service)<---(DAO) 底层为上一级服务的模式。·
2. Struts2的模型驱动(Model Driven),之前所讲的成为属性驱动(Property Driven).
3. 属性驱动与模型驱动的比较:
1---> 属性驱动灵活,准确;模型驱动不灵活,因为很多时候页面所提交过来的参数并不属于模型中的属性,也就是说页面所提交过来的参数与模型中的属性并不一致,这是很常见的情况。
2---> 模型驱动更加符合面向对象编程风格,使我们获得的是对象,而不是一个个离散的值。
小结: 推荐使用属性驱动编写Action。 requestScope相当于request.getAttribute
4. 服务器端代码的单元测试有两种模式:
1---> 容器内测试(Jetty)
2---> Mock<模拟>测试(继承HttpServletRequest,HttpSession、HttpServletResponse等Servlet API).
5. Preparable接口的作用是让Action完成一些初始化工作,这些初始化工作是放在Preparable接口的prepare方法中完成的,该方法会在execute方法执行之前得到调用。
6. 采取请求转发的方式完成表单内容的添加会造成内容的重复插入。
7. 而采用重定向<redirect>的方式实现数据添加将不会产生数据的重复插入。
8. 防止表单重复提交的两种方式:
1---> 通过重定向
2---> 通过Session Token(即 Session令牌):当客户端请求页面时,服务器会通过Token标签生成一个随机数,并且将该随机数放置到session当中,然后将该随机数发向客户端,如果客户第一次
提交那么会将该随机数发往服务器端,服务器端会接收到该随机数,并且与session所保留的随机数进行比较,这时两者的值是相同的,服务器认为是第一次提交并且将更新服务器端得
这个随机数值;如果此时再重复提交,那么客户端发向服务器端的随机数还是之前的那个,而服务器端的随机数则已经发生了变化,两者不同,服务器就认为这是重复提交,进而转向invalid.token
所指向的结果页面。
9. 拦截器(Interceptor):拦截器是Struts2的核心,Struts2的众多功能都是通过拦截器来实现的。
10. 拦截器的配置:
1---> 编写实现Interceptor接口的类
2---> 在struts.xml文件中定义拦截器
3---> 在action中使用拦截器
11. 一旦定义了自己的拦截器,将其配置到action上后,我们需要在action的最后加上默认的拦截器栈:defaultStrack。
Struts2 Lesson5
1. 定义拦截器时可以直接继承AbstractInterceptor抽象类(改来实现了Interceptor接口,并且对init和destory方法进行了空实现),然后实现其抽象方法intercept即可。
2. 方法过滤拦截器(可以对指定方法进行拦截的拦截器)。
3. 在方法过滤拦截器中,如果既没有指定includeMethods参数,也没有指定execludeMethods参数,那么所有的方法都会被拦截,也就是说所有的方法都被认为是includeMethods,
那么只会拦截includeMethods中的方法,没有包含在includeMethods中的方法不会被拦截。
Struts2 Lesson6
1. package元素的abstract属性表示该包是抽象的,不能直接使用,需要有子包继承才可以使用,struts-default这个package就是abstract的,因此,需要我们继承这个包来使用。
2. package元素的namespace属性起到命名空间分割的作用。通常将namespace的属性值定义成页面所在的目录名。
3. 进行文件上传时,必须将表单的method属性设为post,将enctype属性设为multipart/form-data。
4. Struts2在进行文件上传操作时,实际上是通过两个步骤实现的:
1--> 首先将客户端上传的文件保存到struts.multipart.saveDir键所指定的目录中,如果该键所对应的目录不存在,那么就保存到javax.servlet.context.tempdir环境变量所指定的目录中。
2--> Action当中所定义的File类型的成员变量file实际上指向的是临时目录中的临时文件,然后在服务器端通过IO的方式将临时文件写入到指定的服务器端目录中。
5. OGNL(Object Graph Navigation Language):对象图导航语言。
如下面的这段使用ognl所便利的的代码段:
List<Person> list
class Person
{
Address address;
}
class Address
{
A a;
}
class A
{
String s;
}
<s:iterator value="list" id="h">
<s:property value=="#h.address.a.s"/>
</s:iterator>
file: <s:property value="#f.toUpperCase()" --> 还可以自定义属性值
6. Struts2的文件上传实际上通过FileUploadInterceptor拦截器来处理的。