struts2(三)之表单参数自动封装与参数类型自动转换
2017-11-03 09:15
357 查看
前言
对struts2的使用不外乎这几点,参数自动封装,拦截器的使用,数据校验,ognl表达(值栈和actionContext的讲解),struts2的标签,struts2的国际化,
struts2的文件上传下载。 把这几个功能都学会了使用之后,struts2基本上就学完了。
静态参数封装和动态属性封装
动态属性封装又可分为属性驱动和模型驱动
属性驱动又可分为基本属性驱动和对象图导航语言(OGNL,Object Graph Navigation Language)驱动。
DemoActionTest
2)struts.xml的配置
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102163927935-998080592.png)
3)在一个jsp中写入
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102164021920-1352963518.png)
然后进行访问
4)结果
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102164049232-2002571892.png)
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102164112451-2114009099.png)
staticParams拦截器,我们来看看是怎么进行封装的:
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102164258466-433643737.png)
结论:该拦截器会将静态参数放入值栈中,而action就在值栈中的栈顶,自然就会找到该action中的对应属性,然后进行赋值了。
依靠的拦截器为params。
index.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170606763-2067708392.png)
struts.xml
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170659591-605654434.png)
DemoActionTest
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170752966-975265972.png)
测试:
访问index.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170842232-178834372.png)
提交
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170905216-182808868.png)
结果就是成功封装数据并打印出来
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170917201-613388703.png)
2)ognl表达式来封装数据
2.1)封装对象
User.java
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102171517638-1029949310.png)
index.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102171710373-1108167060.png)
struts.xml
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170659591-605654434.png)
DemoActionTest
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102172208420-1175190490.png)
测试:
访问index.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102172340357-1484575694.png)
提交
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102172422138-69802591.png)
结果
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102172358701-2123108415.png)
分析:
在jsp页面中的user.name和user.age其实就是ognl表达式,代表着往根(root,值栈valueStack)中存放值,而值栈中的栈顶元素也就是为当前action,
我们在action中设置user的get、set属性,即可以让存进来的值匹配到,进而将对应属性赋值成功。
2.2)封装List集合
index.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102173107060-1844030447.png)
DemoActionTest
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102174026763-154558995.png)
结果封装成功
分析:
jsp中的users[0].name、users[0].age、users[1].name、users[1].age就是在给值栈中的users集合进行封装对象,users[0]代表list集合中的第一个对象。
2.3)封装map集合
map集合和上面的list集合类似,只不过在编写ognl表达式有些不同,
users["lance"].name、users["lance"].age,users["lance"]代表的是map中key为lance的value,也就找到了key为lance的User对象,然后在进行封装数据即可。
实现数据模型的步骤:
实现一个ModelDriven的接口
实现接口里的方法getModel()
在使用模型驱动的时候,数据模型必须由我们来完成实例化
是由一个ModelDriven的拦截器帮我们做的
1)实现ModelDriven接口和抽象方法
实现ModelDriven接口,提供一个方法getModel(),编写对象实例。
DemoActionTest
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102175058982-2023883936.png)
index.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102175249310-1671552838.png)
分析:
这有一个专门的拦截器,叫做modelDriven。
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102175333060-1580658760.png)
其实原理就是,该拦截器将getModel方法返回的结果压入值栈,而我们的表单参数会从值栈中从上往下进行查找,自然就直接将参数封装到User对象中了。
非常方便,不知道大家发现了没有,从表单元素提交过来的都是String类型的,而我们在servlet中获取到表单元素后,得到的是Object类型,也就是需要我们自己手动
转型,但是在struts2中,我们却不需要,是因为有这么一个机制,参数类型自动转型,获取过来的参数都是String类型的,但是如果我们需要int型,double型等,都会
帮我们自己转换。
实际开发中用户输入的数据都是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.字符串数组:默认用逗号+空格,连接一个字符串
test.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102200044279-1287627808.png)
DemoActionTest
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102200125123-1941739574.png)
分析:
全部都自动转型了,这里需要注意一点,在使用struts2中的日期自动转型时,表单中的日期字符串的格式是固定的,必须是2014/12/06,也就是yyyy/mm/dd这样的格式,
其他格式的话,不能够转型成功,这对有些人来说,就有些不舒服,使用习惯不一样,但是没关系,struts2能够让我们自定义类型转换器,格式让我们自己来决定。
想了解转换器的实现原理:http://blog.csdn.net/xtayfjpk/article/details/16826649
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102200401013-1159323680.png)
从这张图可以看的出来如果你想要自定义一个类型转换器的话需要集成StrutsTypeConverter类
只需要两步即可完成:
1)继承DefaultTypeConverter类,重写convertValue方法
2)注册转换器。也就是该转换器的作用范围。局部配置和全局配置。
1)创建一个MyConvertor继承StrutsTypeConverter类
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201009029-1804846472.png)
2)注册类型转换器
2.1)注册,局部配置
位置:action类同包
名称:actionClass-conversion.properties
actionClass:action类的类名
conversion.properties:固定名
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201431904-1254885583.png)
内容:
属性=转换器类的全限定类名
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201503576-442374218.png)
这样一来,我们自定义的转换器就只能在Demo01Action中属性名为date身上使用了,超过了该范围,就会使用struts2默认的转换器。
2.2)注册,全局配置
位置:src
名称:xwork-conversion.properties
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201633857-544740250.png)
内容:需要转换得类=转换器
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201708310-250295440.png)
全局配置后,所有在struts2中使用Date型的都会用我们写的转换器进行转换。
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201804451-491200090.png)
解决办法:配置回显结果试图
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201830138-1210733592.png)
总结:
1)首先,我们在也不需要手动表单提交的参数了,并且也无需对获取到的参数进行转换类型了,这将非常方便,使用起来真的非常爽,直接拿过来用即可。
而我们常用的应该为动态参数封装了,其中更为常用的是使用modelDriven,或者直接使用ognl表达式进行封装。
2)感受到了struts2架构中的拦截器的作用,确实帮我们做了不少事情,了解了几个拦截器的功能,比如params,staticParams、modelDriven等的使用。
喜欢就点个“推荐”哦!
对struts2的使用不外乎这几点,参数自动封装,拦截器的使用,数据校验,ognl表达(值栈和actionContext的讲解),struts2的标签,struts2的国际化,
struts2的文件上传下载。 把这几个功能都学会了使用之后,struts2基本上就学完了。
一、数据自动封装概述
Struts2提供了一些基于拦截器的数据封装方式,一共有四种,分为静态参数封装和动态属性封装
动态属性封装又可分为属性驱动和模型驱动
属性驱动又可分为基本属性驱动和对象图导航语言(OGNL,Object Graph Navigation Language)驱动。
package com.jxlg.web.action; import com.opensymphony.xwork2.ActionSupport; public class DemoActionTest extends ActionSupport{ private String username; private String age; public String addUser(){ System.out.println(username+"---"+age); return null; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } }
DemoActionTest
2)struts.xml的配置
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102163927935-998080592.png)
3)在一个jsp中写入
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102164021920-1352963518.png)
然后进行访问
4)结果
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102164049232-2002571892.png)
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102164112451-2114009099.png)
staticParams拦截器,我们来看看是怎么进行封装的:
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102164258466-433643737.png)
结论:该拦截器会将静态参数放入值栈中,而action就在值栈中的栈顶,自然就会找到该action中的对应属性,然后进行赋值了。
三、动态参数封装
属性驱动和模型驱动都非常重要,都需要掌握,如果还不会ognl表达式,那么可以在学完ognl表达后在回过头来看即可。3.1、属性驱动
1)普通属性驱动,提供get、set方法。跟静态参数封装一样,只不过这里获取的是表单中的参数,也就是请求发送过来的数据。依靠的拦截器为params。
index.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170606763-2067708392.png)
struts.xml
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170659591-605654434.png)
DemoActionTest
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170752966-975265972.png)
测试:
访问index.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170842232-178834372.png)
提交
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170905216-182808868.png)
结果就是成功封装数据并打印出来
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170917201-613388703.png)
2)ognl表达式来封装数据
2.1)封装对象
User.java
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102171517638-1029949310.png)
index.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102171710373-1108167060.png)
struts.xml
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102170659591-605654434.png)
DemoActionTest
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102172208420-1175190490.png)
测试:
访问index.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102172340357-1484575694.png)
提交
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102172422138-69802591.png)
结果
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102172358701-2123108415.png)
分析:
在jsp页面中的user.name和user.age其实就是ognl表达式,代表着往根(root,值栈valueStack)中存放值,而值栈中的栈顶元素也就是为当前action,
我们在action中设置user的get、set属性,即可以让存进来的值匹配到,进而将对应属性赋值成功。
2.2)封装List集合
index.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102173107060-1844030447.png)
DemoActionTest
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102174026763-154558995.png)
结果封装成功
分析:
jsp中的users[0].name、users[0].age、users[1].name、users[1].age就是在给值栈中的users集合进行封装对象,users[0]代表list集合中的第一个对象。
2.3)封装map集合
map集合和上面的list集合类似,只不过在编写ognl表达式有些不同,
users["lance"].name、users["lance"].age,users["lance"]代表的是map中key为lance的value,也就找到了key为lance的User对象,然后在进行封装数据即可。
3.2、模型驱动(开发中采用方式)
要想使用模型驱动,数据模型和动作类必须分开写。实现数据模型的步骤:
实现一个ModelDriven的接口
实现接口里的方法getModel()
在使用模型驱动的时候,数据模型必须由我们来完成实例化
是由一个ModelDriven的拦截器帮我们做的
1)实现ModelDriven接口和抽象方法
实现ModelDriven接口,提供一个方法getModel(),编写对象实例。
DemoActionTest
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102175058982-2023883936.png)
index.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102175249310-1671552838.png)
分析:
这有一个专门的拦截器,叫做modelDriven。
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102175333060-1580658760.png)
其实原理就是,该拦截器将getModel方法返回的结果压入值栈,而我们的表单参数会从值栈中从上往下进行查找,自然就直接将参数封装到User对象中了。
四、struts中的数据类型转换
上面我们知道了struts2的方便之处,不用我们自己手动来获取请求参数了,struts2中的某些拦截器已经帮我们全部解决好了,我们只需要写get、set方法即可,真是非常方便,不知道大家发现了没有,从表单元素提交过来的都是String类型的,而我们在servlet中获取到表单元素后,得到的是Object类型,也就是需要我们自己手动
转型,但是在struts2中,我们却不需要,是因为有这么一个机制,参数类型自动转型,获取过来的参数都是String类型的,但是如果我们需要int型,double型等,都会
帮我们自己转换。
4.1、开发中数据类型变化
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.字符串数组:默认用逗号+空格,连接一个字符串
test.jsp
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102200044279-1287627808.png)
DemoActionTest
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102200125123-1941739574.png)
分析:
全部都自动转型了,这里需要注意一点,在使用struts2中的日期自动转型时,表单中的日期字符串的格式是固定的,必须是2014/12/06,也就是yyyy/mm/dd这样的格式,
其他格式的话,不能够转型成功,这对有些人来说,就有些不舒服,使用习惯不一样,但是没关系,struts2能够让我们自定义类型转换器,格式让我们自己来决定。
想了解转换器的实现原理:http://blog.csdn.net/xtayfjpk/article/details/16826649
4.2、自定义类型转换器
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102200401013-1159323680.png)
从这张图可以看的出来如果你想要自定义一个类型转换器的话需要集成StrutsTypeConverter类
只需要两步即可完成:
1)继承DefaultTypeConverter类,重写convertValue方法
2)注册转换器。也就是该转换器的作用范围。局部配置和全局配置。
1)创建一个MyConvertor继承StrutsTypeConverter类
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201009029-1804846472.png)
2)注册类型转换器
2.1)注册,局部配置
位置:action类同包
名称:actionClass-conversion.properties
actionClass:action类的类名
conversion.properties:固定名
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201431904-1254885583.png)
内容:
属性=转换器类的全限定类名
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201503576-442374218.png)
这样一来,我们自定义的转换器就只能在Demo01Action中属性名为date身上使用了,超过了该范围,就会使用struts2默认的转换器。
2.2)注册,全局配置
位置:src
名称:xwork-conversion.properties
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201633857-544740250.png)
内容:需要转换得类=转换器
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201708310-250295440.png)
全局配置后,所有在struts2中使用Date型的都会用我们写的转换器进行转换。
4.3、转换失败后的处理(重点)
当转换失败后,页面的提示![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201804451-491200090.png)
解决办法:配置回显结果试图
![](https://images2017.cnblogs.com/blog/999804/201711/999804-20171102201830138-1210733592.png)
总结:
1)首先,我们在也不需要手动表单提交的参数了,并且也无需对获取到的参数进行转换类型了,这将非常方便,使用起来真的非常爽,直接拿过来用即可。
而我们常用的应该为动态参数封装了,其中更为常用的是使用modelDriven,或者直接使用ognl表达式进行封装。
2)感受到了struts2架构中的拦截器的作用,确实帮我们做了不少事情,了解了几个拦截器的功能,比如params,staticParams、modelDriven等的使用。
喜欢就点个“推荐”哦!
相关文章推荐
- struts2(二) 表单参数自动封装和参数类型自动转换
- Struts2(接受表单参数)请求数据自动封装和数据类型转换
- struts2(二) 表单参数自动封装和参数类型自动转换
- struts2中自动封装参数及类型转换
- ###Springmvc封装复杂表单数据:表单提交多个实体类的参数【对象类型参数,自动封装】name属性值不能重复。和实体类属性名一致
- 深入分析JavaWeb 45 -- Struts2封装请求参数与类型转换
- struts2-OGNL和类型转换(structs 自动数据表单获取)
- Struts2学习之2(请求参数的封装,类型转换,输入验证,自定义拦截器)
- Struts2请求数据自动封装和数据类型转换
- 解决struts2基础数据类型自动转换,输入字母报错问题!
- java基本数据类型与字符串之间的转换(基本数据类型、对象封装类、自动装箱、自动拆箱)
- Action参数封装过程中,数据类型转换问题
- JAVAWEB开发之Struts2详解(二)——Action接受请求参数、类型转换器、使用Struts2的输入校验、以及遵守约定规则实现Struts2的零配置
- struts2新增json返回类型,自动将action中的的成员变量转换成json字符串
- struts2页面到action中date类型自动转换
- Struts2:类型转换之批量封装Set集合类型的属性(二)
- Struts2:类型转换之批量封装Set集合类型的属性
- Struts2:类型转换之批量封装Set集合类型的属性(一)
- 函数参数的自动隐式类类型转换只能一次
- Struts2的知识整理总结(三)—— 数据封装和类型转换