(十二)struts2的类型转换
所有的MVC框架,都属于表现层的解决方案,都需要负责收集用户请求参数,并将请求参数传给应用的控制器组件。
这时问题出现了,所有的请求参数都是字符串类型数据,因此MVC框架必须具备将这些字符串请求参数转换成相应的数据类型。
struts2提供了非常强大的类型转换机制,struts2的类型转换是基于OGNL表达式。
struts2提供了很好的扩展性,开发者可以开发出自己的类型转换器。完成字符串到自定义类型之间的转换。
如果类型转换中出现未知异常,开发者无须关心异常处理,struts2的conversionError拦截器会自动处理该异常,并且在页面上生成提示信息。
servlet中的类型转换
表单中提交的所有数据都是字符串类型
例如我们有一个User类,name为String类型,age为int类型,birthday为Date类型,我们必须在servlet中获取表单传入的参数,然后将其进行类型转换,然后封装到User对象中。
上述需要程序员自己进行类型转换操作,比较繁琐。
对于一个MVC框架而言,一样需要将请求参数封装成对象,也必须将请求参数转换成对象属性的数据类型,这就是类型转换的意义。
Struts2内建的类型转换器
struts内建的类型转换器能自动将我们的表单数据(字符串)转换成对应的数据类型。
完成字符串和日期类型之间的转换时,日期格式必须使用请求用户本地的格式。一般是yyyy-MM-dd,如果输入的日期格式不是本地的日期格式,例如我们输入1996/01/31,就会出现错误,类型转换失败。
自定义类型转换器
需求:
当我们在表单中输入的日期格式不是本地的格式时,就会出现类型转换错误,我们也经常需要将字符串转换成其他的格式,例如字符串转换成对象之类的操作,这时我们就需要自定义类型转换器。
struts2的类型转换器实际上是基于OGNL实现的。xwork集成了OGNL。
实现类型转换器必须实现TypeConverter接口。这个接口的方法太过复杂,所以还提供了一个该接口的实现类DefaultTypeConverter。
我们重写DefaultTypeConverter类的convertValue方法即可。
我们基于DefaultTypeConverter类实现类型转换器时,将字符串转换成我们需要的类型通过convertValue方法实现,将我们的类型转换成字符串也是通过convertValue方法实现,因此我们必须判断转换的类型来实现不同的逻辑。
为了简化类型转换器的实现,struts2提供了一个StrutsTypeConverter抽象类,这个类是DefaultTypeConverter类的子类。
我们看下这个类的源码 :
继承DefaultTypeConverter
public abstract class StrutsTypeConverter extends DefaultTypeConverter { //重写DefaultTypeConverter类的convertValue方法
public Object convertValue(Map context, Object o, Class toClass) {
//如果要转换的类型是字符串类型,也就是把我们的类型转换成字符串,调用convertToString方法
if (toClass.equals(String.class)) {
return convertToString(context, o);
}
//如果参数是字符串数组,也就是将字符串转换成我们需要的类型,调用convertFromString方法
else if (o instanceof String[]) {
return convertFromString(context, (String[]) o, toClass);
}
//如果参数是字符串,也就是将字符串转换成我们需要的类型,调用convertFromString方法
else if (o instanceof String) {
return convertFromString(context, new String[]{(String) o}, toClass);
} else {
return performFallbackConversion(context, o, toClass);
}
} protected Object performFallbackConversion(Map context, Object o, Class toClass) {
return super.convertValue(context, o, toClass);
} //将字符串转换成我们需要的类型的方法
public abstract Object convertFromString(Map context, String[] values, Class toClass); //将我们的类型转换成字符串的方法
public abstract String convertToString(Map context, Object o);
} 三个参数 :
Map context:OGNL的上下文。暂时还没学,后面会学到,暂时不用管。
value:需要转换的参数。
toClass:转换后的类型
例子:
需求:我们将我们前面的注册案例中的生日改成 yyyy/MM/dd类型
(1)创建自定义类型转换器
public class MyConverter extends StrutsTypeConverter {
//日期转换器,转换成指定的类型
private DateFormat format=new SimpleDateFormat("yyyy/MM/dd");
//将字符串转换成日期类型
public Object convertFromString(Map context, String[] values, Class toClass) {
//判断参数是否为空
if(values==null||values.length==0){
return null;
}
//我们只有一个参数,就是表单的birthday
String date=values[0];
//判断目标类型是否是Date
if(toClass==java.util.Date.class){
try {
//进行转换
return format.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
}
return null;
}
//将日期类型转换成字符串
public String convertToString(Map context, Object o) {
//判断当前参数是否是日期类型
if(o instanceof java.util.Date){
return format.format(o);
}
return null;
}
}
(2)注册类型转换器
局部类型转换器
按照属性来注册
如果属性都在action中,那么应该创建一个文件 Action名字-conversion.properties ,例如LoginAction-conversion.properties
如果属性放到了javaBean中,那么创建一个文件 javaBean名称-conversion.properties 例如 User-conversion.properties 文件由键值对组成。
键为需要转换的属性名字,值为自己实现的类型转换器全类名。 我们创建 User-conversion.properties 内容 birthday=com.cad.web.convert.MyConverter 这时我们注册时使用 1996/01/24这种格式进行注册就不会出现类型转换错误。
用户提交请求时,请求中的birthday参数会先被该类型转换器处理。 全局类型转换器
所有的Action都能用。我们需要在src目录下创建一个 xwork-conversion.properties 的文件 因为是全局的,就不存在只对birthday这个属性进行转换。
这里的键是要转换的类型,值还是类型转换器类。 我们创建 xwork-conversion.properties
内容 java.util.Date=com.cad.web.convert.MyConverter
这样当我们输入日期的表单时,就可以使用我们自定义的日期格式。
类型转换中的错误处理
struts2提供了一个名为conversionError的拦截器,这个拦截器被注册在默认拦截器栈中。
当类型转换器执行类型转换出现错误时,该拦截器负责将对应错误封装成表单域错误(fieldError),并将错误信息放入ActionContext中。
当拦截器对转换异常进行处理后,系统会跳转到名为input的逻辑视图。
我们在struts.xml中配置 <result name="input">/regist.jsp</result>
当类型转换失败后,再跳转到注册页面 跳转到input视图以后,我们发现没有任何错误提示信息。我们前面讲过conversionError拦截器会将转换错误封装成fieldError,并放在ActionContext中。
为了在页面中输出错误信息,我们需要使用struts的标签。我们先使用一些,后面会详细介绍。 我们在页面添加<s:fielderror></s:fielderror>标签
当我们类型转换失败后,就会输出错误信息。 我们发现输出的错误信息是英文的,我们希望能变为中文的提示信息。 我们只需要在创建一个properties文件 文件名为 javabean名称.properties 键为invalid.fieldvalue.属性名称 例如 :invalid.fieldvalue.birthday
值为要输出的内容 例如 invalid.fieldvalue.birthday=生日格式不正确
(十二)struts2的类型转换的更多相关文章
- struts2学习笔记之十二:struts2对异常的自动处理
在UserAction类中引发异常,但是不处理 package com.djoker.struts2; import java.util.Date; import org.apache.struts2 ...
- struts2官方 中文教程 系列十二:控制标签
介绍 struts2有一些控制语句的标签,本教程中我们将讨论如何使用 if 和iterator 标签.更多的控制标签可以参见 tags reference. 到此我们新建一个struts2 web 项 ...
- 第十二章Fundamental Data Types 基本数据类型
目录: 12.1 数值概论 12.2整数 12.3浮点数 12.4 字符和字符串 12.5布尔变量 12.6枚举类型 12.7具名常量 12.8数组 12.9创建你自己的类型 12.1 数值概论 ...
- 关于Struts2的类型转换详解
详细出处参考:http://www.jb51.net/article/35465.htm 一.类型转换的意义 对于一个智能的MVC框架而言,不可避免的需要实现类型转换.因为B/S(浏览器/服务器)结构 ...
- J2EE进阶(十二)SSH框架整合常见问题汇总(三)
在挂失用户时,发现userid值为空,但是在前台输入处理账号22时,通过后台输出可以看出,后台根据前端输入在数据库中查询到结果对象并输出该对象的userid,而且Guashi对象也获取到了其值. 解决 ...
- Struts2之类型转换
jsp提交的数据全部是String类型,Struts2也是通过request.getParameter(name)取得String类型的数据,并通过拦截器将String转换成各种类型的数据,然后通过g ...
- JAVA基础知识总结:一到二十二全部总结
>一: 一.软件开发的常识 1.什么是软件? 一系列按照特定顺序组织起来的计算机数据或者指令 常见的软件: 系统软件:Windows\Mac OS \Linux 应用软件:QQ,一系列的播放器( ...
- 201871020225-牟星源《面向对象程序设计(java)》第十二周学习总结
201871020225-牟星源<面向对象程序设计(java)>第十二周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...
- 第十二周java实验作业
实验十二 图形程序设计 实验时间 2018-11-14 1.实验目的与要求 (1) 掌握Java GUI中框架创建及属性设置中常用类的API: Java的集合框架实现了对各种数据结构的封装. jav ...
随机推荐
- PHP实现一个二维码同时支持支付宝和微信支付
实现思路 生成一个二维码,加入要处理的url连接 在用户扫完码后,在对应的脚本中,判断扫码终端,调用相应的支付 若能够扫码之后能唤起相应app,支付宝要用手机网站支付方式,微信要使用jsapi支付方式 ...
- HBase ——Shell操作
HBase --Shell操作 Q:你觉得HBase是什么? A:一种结构化的分布式数据存储系统,它基于列来存储数据. 基于HBase,可以实现以廉价PC机器集群存储海量数据的分布式数据库的解决方案. ...
- Vue学习笔记-jsonl转换显示工具JsonView安装及使用
一 使用环境: windows 7 64位操作系统 二 jsonl转换显示工具JsonView安装及使用 1.下载: https://github.com/gildas-lormeau/JSONV ...
- python进阶(6)深拷贝和浅拷贝
深拷贝和浅拷贝 不管对于浅拷贝.还是深拷贝,针对不可变对象str.int.tuple(有点特殊).boolean,它的内存地址是不变的,拷贝的仅仅是值 import copy a = 1 b = co ...
- 看完我的笔记不懂也会懂----less
目录 Less学习 语法篇 注释 变量 映射(Maps) @规则嵌套和冒泡 less中的嵌套规则 less中的混合 less的运算 extend延伸/继承 less忽略编译(转义) 导入(Import ...
- Python3+pygame实现的俄罗斯方块 代码完整 有演示效果
一.简单说明 80.90后的小伙伴都玩过"俄罗斯方块",那种"叱咤风云"场景 偶尔闪现在脑海 真的是太爽了:如果没有来得及玩过的同学,这次可以真正的自己做一个了 ...
- CentOS7安装 xmlsec1 编译并运行官方示例
1. 自动安装下列软件和依赖(默认已安装libxml2和libxslt) yum install xmlsec1-openssl xmlsec1-openssl-devel 2. 查看官网 www.a ...
- python引用C++ DLL文件若干解释及示例
python引用C++ DLL文件若干解释及示例 首先说一下,python不支持C++的DLL,但是支持C的DLL:C++因为和C兼容可以编译为C的DLL,这是下面文章的背景与前提 首先我这儿的示例使 ...
- gRPC在 ASP.NET Core 中应用学习
一.gRPC简介: gRPC 是一个由Google开源的,跨语言的,高性能的远程过程调用(RPC)框架. gRPC使客户端和服务端应用程序可以透明地进行通信,并简化了连接系统的构建.它使用HTTP/2 ...
- C++高精度计算(大整数类)
Java和Pathon可以不用往下看了 C++的基本数据类型中,范围最大的数据类型不同编译器不同,但是最大的整数范围只有[-2^63-2^63-1](对应8个字节所对应的二进制数大小).但是对于某些需 ...