一、封装请求正文到对象中(非常重要)
1、如何封装静态请求参数?
在 struts.xml
配置文件中,通过参数注入的方式,给动作类的参数注入值。相当于调用的是该参数的 setter方法
。控制台输出的是 张三,18
,如下图所示:
原因:是由默认的
拦截器栈
中的一个 拦截器staticParams
来完成参数注入的。该拦截器栈在
struts-default.xml
文件中定义。为了演示方便,我们把写在 struts-default.xml
中默认的拦截器写在 struts.xml
中进行显示出来,如下图所示:当我们把黄色框框中的
<interceptor-ref name="staticParams"/>
这句代码注释掉后,再次访问该 action 时,在控制台输出的是 null,0
。
2、如何封装动态请求参数?:开发时用到的
通过用户的表单封装请求正文参数。
1、动作类作为实体模型(即:数据模型与动作类写在一起)
实体模型:Entity,对应数据库中表的记录(注意:类对应的是表结构,而对象对应的是一条记录)
原因:是由
params拦截器
完成的。2、动作类和实体模型分开
3、模型驱动:建立动作类和模型分开的前提下(
开发中采用的方式
)此处的学习目标:目前先记住怎么写,要想理解,必须等讲完
OGNL表达式
之后。原因:是由一个
modelDriven拦截器
完成的。
二、用户注册案例(重点)
1、数据建模(数据库和实体模型)
2、建立业务层接口 + 建立业务层实现类
3、建立持久层接口 + 建立持久层实现类(暂时没有具体实现)
4、拷贝jar包和配置文件
拷贝数据库工具类jar包:commons-dbutils-1.4.jar
和 mysql-connector-java-5.0.8-bin.jar
到 /WebRoot/WEB-INF/lib
中,再拷贝数据源工具类jar包:commons-dbcp-1.4.jar
和 commons-pool-1.6.jar
到 /WebRoot/WEB-INF/lib
中,再将与之相对应的配置文件 dbcpconfig.properties
拷贝至项目路径中的 /src
目录下,若该配置文件有乱码,则点击该配置文件 右键/Properties/Text file encoding/Other/UTF-8
,OK即可。
5、在项目中新建一个 util的包 ,将代码 DBCPUtil.java 拷贝
如下图所示:
6、持久层实现类(具体实现)
如下图所示:
7、表现层使用Struts2框架实现
- 动作类
- 配置文件
- 注册界面和结果视图
注册页面:
结果视图:
三、数据类型的转换(明白原理即可,实际开发中几乎不用)
1、开发中的情况:
实际开发中用户通过浏览器输入的数据都是 String
或者 String[]
。
- String/String[] ————> 填充模型(set方法) ————> POJO(plain old java object)
pojo中有java的数据类型。 - POJO ————> 获取(get方法) ————> 页面展示:String
2、类型转换的两种情况:
- 写数据:(增,删,改)都是String或String[]数组转换为其他类型。
- 读数据:(查)其他类型转换为String。
3、Struts2提供的常用类型转换:
- a. 基本数据类型
自动转换
。 - b. 日期类型:默认按照
本地日期格式
转换(yyyy-MM-dd)。 - c. 字符串数组:默认用
逗号+空格
,连接成一个字符串。
4、自定义类型转换器(知道即可)
示例:把日期格式按照 MM/dd/yyyy的格式转换
-
4.1、先看看Struts2中的类型转换器的结构:
UML图如下:
DefaultTypeConverter.java
StrutsTypeConverter.java -
4.2、编写自己的类型转换器(编写一个类继承StrutsTypeConverter,实现其抽象方法)
-
4.3、注册类型转换器
局部类型转换器:只能指定javabean中的属性。
按照属性
来注册。在属性所属的 javabean 的包下建立一个.properties
文件。
文件名称为:javabean名称-conversion.properties
如下图所示:此时,只能是User能够使用。其余的javabean用不了。
全局类型转换器:(推荐)
按照要转换的数据类型
来注册。at the top on classpath
,建立一个固定名称xwork-conversion.properties
的属性文件。
5、转换失败后的处理(需要掌握)
当转换失败后,页面提示:
上面的显示给客户端的用户看,太难看了,不好。
解决办法:配置回显结果视图
问题
:配置了回显视图后,当转换失败时,可以回到请求页面,但是表单数据却都没了?肿么办?解决办法:显示错误提示:借助Struts2的标签库。如下图所示:
回显数据:使用struts2的标签库生成表单。(建议使用)如下图所示:
演示效果如下图所示:
错误信息中文提示:使用的是struts2的国际化。
效果如下图所示:
问题:类型转换器当转换失败后,如何进入input视图的?
原因:是由一个叫做
conversionError
的拦截器完成的。注意:要想使用类型转换中的错误处理,在
定义Action
时必须继承 ActionSupport
。
四、数据验证
用户的输入验证,必须做,且工作量巨大。
1、验证的方式
客户端验证:javascript
服务端验证:逻辑验证(我们的代码)
注意:如果客户端和服务端二选一的话,服务器端的不能省。
实际开发中:客户端 + 服务端
2、Struts2的服务端验证
- 2.1、编程式验证
前提:动作类必须继承ActionSupport。
在代码中编写验证规则。
a、针对动作类中的 所有动作方法
进行验证:
在动作类中重写 public void validate()
方法。如下图所示:
用到了针对
java.lang包
中String的扩展的 工具类StringUtils
:演示视图如下图所示:
但是当我们再写一个动作方法时:
由此可知,当重写了validate方法后,该验证方法会对动作类中的所有动作方法进行验证。
b、针对动作类中的 某个动作方法
进行验证:
针对上面的问题,
解决办法1:给不需要验证的动作方法添加一个 @SkipValidation注解
。
解决办法2:
validation方法遵守书写规范。
即:定义验证方法的名称:validate+动作名称 ,动作名称的首字符还要大写。
解决办法1和解决办法2的使用时机:
需要验证的动作方法少,用解决办法2。
需要验证的动作方法多,用解决方式1。(简言之:挑少的写)
所有编程式验证的弊端:硬编码。(写死了)
- 2.2、声明式验证(推荐)
通过编写验证规则
的xml文件
。需要验证时,编写xml文件,不要验证时,就不编写。
优势:解决了2.1编程式验证的弊端。
a、针对动作类中的 所有动作方法
进行验证:
在动作类所在的包中,建立一个 ActionClassName-validation.xml
的文件,内容如下:
图片中的
xwork-validator-1.0.3.dtd文件
在 struts-2.3.15.3-allstruts-2.3.15.3appsstruts2-blankWEB-INFlibxwork-core-2.3.15.3.jarxwork-validator-1.0.3.dtd
中。注意:当使用ActionClassName-validation.xml来命名文件时,它是一个动作类验证器。会验证动作类中的所有动作方法。
b、针对动作类中的 某个动作方法
进行验证:
在动作类所在的包中建立一个 xml文件
,名称为 ActionClassName-ActionName-validation.xml
。内容如下:
注意:动作名称是配置文件struts.xml中package元素的name属性的取值。
- 2.3、Struts2内置的常用声明式验证器
1、所在位置:xwork-core-2.3.15.3.jarcomopensymphonyxwork2validatorvalidatordefault.xml
,该文件内容如下图所示:
2、验证器注入参数
例如:我们使用 requiredstring
,默认是去空格,当我们不想去空格时,就可以给该验证器注入参数。
基于字段的方式和基于验证器的方式如下:
效果如下图所示:
3、声明式基于字段的常用验证器案例
(1)注册页面 student.jsp
,如下图所示:
(2)注册页面效果图,如下图所示:
(3)实体模型(数据模型:JavaBean)
Student.java
,如下图所示:(4)
struts.xml
中的配置(5)动作类
StudentAction.java
,如下图所示:(6)声明式验证文件
StudentAction-addStudent-validation.xml
如下:(7)整体效果,如下图所示: