博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(十二)struts2的类型转换
阅读量:7227 次
发布时间:2019-06-29

本文共 5513 字,大约阅读时间需要 18 分钟。

所有的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类的子类。    我们看下这个类的源码 :

 

  

继承DefaultTypeConverterpublic 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中配置 
/regist.jsp
当类型转换失败后,再跳转到注册页面 跳转到input视图以后,我们发现没有任何错误提示信息。我们前面讲过conversionError拦截器会将转换错误封装成fieldError,并放在ActionContext中。 为了在页面中输出错误信息,我们需要使用struts的标签。我们先使用一些,后面会详细介绍。 我们在页面添加
标签 当我们类型转换失败后,就会输出错误信息。 我们发现输出的错误信息是英文的,我们希望能变为中文的提示信息。 我们只需要在创建一个properties文件 文件名为 javabean名称.properties 键为invalid.fieldvalue.属性名称 例如 :invalid.fieldvalue.birthday 值为要输出的内容 例如 invalid.fieldvalue.birthday=生日格式不正确

  

 

 

转载于:https://www.cnblogs.com/yuexiaoyun/p/9448873.html

你可能感兴趣的文章
firebug重新载入页面获取源码
查看>>
我的友情链接
查看>>
5月末周中国.COM总量净增1.2万个 美国净减2.6万个
查看>>
Elasticsearch数据建模-关联查询
查看>>
我的友情链接
查看>>
CentOS 下安装 Lnmp
查看>>
redis系列:通过日志案例学习string命令
查看>>
世界冠军之路:菜鸟车辆路径规划求解引擎研发历程
查看>>
Linux-sendmail
查看>>
关于BSTR的困惑
查看>>
什么时候使用HashMap?它有什么特点?
查看>>
框架名
查看>>
编译安装PHP
查看>>
插入透明背景Flash的HTML代码
查看>>
无标题
查看>>
我的友情链接
查看>>
Web前端入门学习(3)——CSS选择器
查看>>
DNS的搭建
查看>>
Apache/Nginx 访问日志分析脚本
查看>>
Curator的使用
查看>>