所有的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=生日格式不正确

  

 

最新文章

  1. IOC Unity
  2. Tray - a SharedPreferences replacement for Android
  3. 基于C/S架构的3D对战网络游戏C++框架 _02系统设计(总体设计、概要设计)
  4. C# winform Listbox添加和删除items
  5. FMX的综合评价
  6. C# list 去重
  7. Codeforces 600B Queries about less or equal elements(二分查找)
  8. Xcode6中autolayout和sizeclass的使用
  9. Css3渐变实例Demo(一)
  10. js库编写的环境和准备工作
  11. Sting和StringBuffer的区别
  12. Android开发 更改返回button的图标
  13. JS正则替换字符串
  14. PHP全选择删除功能
  15. Svm相关
  16. 免费搭建wordpress博客有感
  17. Css - 精灵图
  18. 通俗理解webService及.net中的使用方法
  19. 【LOJ】#2523. 「HAOI2018」奇怪的背包
  20. Android 最基础生命周期及旋转屏幕问题

热门文章

  1. nasm aat函数 x86
  2. Flutter: AnimatedList 一个滚动容器,可在插入或移除项目时为其设置动画
  3. 快速读懂 HTTP/3 协议
  4. Python 股票市场分析实战
  5. 将日志发送到log日志文件中
  6. js实现element中可清空的输入框(2)
  7. 后端程序员之路 16、信息熵 、决策树、ID3
  8. uni-app创建项目
  9. [转载]Android MVC,MVP和MVVM 思想&amp;例子
  10. 日志文件迁移至OSS