`

struts2 converter 之类型转换器

 
阅读更多

1. 前面讲的自定义类型转换器是基于 OGNL 的 DefaultTypeConverter 类并实现 convertValue() 方法,两个转换方向的逻辑都写在这一个方法中。而 Struts 2 为我们提供了一个 DefaultTypeConverter 的抽象子类 StrutsTypeConverter 来继承,并实现其中两个抽象方法 convertFromString() 和 convertToString(),这要简单易懂。对比 Struts 1 的转换器是要实现 org.apache.commons.beanutils.Converter 接口,以及它的 convert() 方法的。

2. 注意,上面的 convertFromString() 的第二个参数是一个字符串数组,所以可为请求的数组(如请求串为 ?u=1&u=2&u=3)定义转换器,Action 中相应的属性就应为数组或 List,这一方法的返回值也该为相应的类型(数组或List,要通过第三个参数 toClass 来判断是返回数组还是 List 了)。

3. 字符串(如 "user,pass") 转换成 Action 中的复合属性(如 User user) 前面是自定了类型转换器。除此之外,还可以 Struts 2 内置的 OGNL 表达式,更简单的转换,不用写转换器。例如,你的 Action 有属性 User user,只要在 jsp 页面的输入框命名为 user.name  和 user.pass 即可:
        <input type="text" name="user.name"/> 或用标签:<s:textfield name="user.name" label="用户名"/>
        <input type="text" name="user.pass"/>  或用标签:<s:textfield name="user.pass" label="密 码"/>
    提交后,Struts 2 即会帮你构造 User 对象(user = new User()),并赋上属性值(user.setName(),user.setPass()),最后 user 对象赋给 Action (xxxAction.setUser(user))。所以要明白有三个必备的东西:
        1) User 要用一个默认构造方法 2) User 要有对应 name 和 pass 的设置方法 setName() 和 setPass() 3) Action 要有 user 属性的设置方法 setUser(),getUser() 也是要的,至于功用后面能看到。
其实在 Struts 1 中也有这种用法,不过那是在 BeanUtils 中实现的。

4. 如果 Action 中的属性是 Map<String, User> users; 那么与此对应的表单写法就是:(用标签来写)
        <s:textfield name="users['one'].name" label="第一个用户名"/>
        <s:textfield name="users['one'].name" label="第一个密码"/>
        <s:textfield name="users['two'].name" label="第二个用户名"/>
        <s:textfield name="users['two'].name" label="第二个密码"/>
    应该不难想像,这个表单提交后,users  中存储的是什么吧!
    如果是对于 Action 中的  List 属性,List<User> users; 那么与此对应的表单写法就是:
        <s:textfield name="users[0].name" label="第一个用户名"/>
        <s:textfield name="users[0].name" label="第一个密码"/>
        <s:textfield name="users[1].name" label="第二个用户名"/>
        <s:textfield name="users[1].name" label="第二个密码"/>

5. 归纳前面3、4、5 几点,Struts2 的 Action 在设置每一个属性时都会 get 一下相应的元素 getUser() 或 getUsers()。
    对于 3,在设置 user.name 和 user.pass 之前都会 getUser() 来获取 user 属性,如果 user 为 null 就构造 User 对象,然后设置相应的值。假如声明的时候就已构造好 User 对象,如有其他属性如 age=18,并不会被覆盖。 
   对于 4 和 5,也是在设置每一个属性前都会调用 getUsers() 判断声明的 Map 或 List 是否为 null,是则构造对应的 HashMap 或  ArrayList() 对象;接着根据 Key 或下标去获取相应位置的元素,如果不存在或为 null 则构造之,然后设置相应属性值。由此可见,若某元素的某个属性未重设值则保留原值,若原来Map或List 已有多个元素,也只会改变到 Key 或索引所对应元素的某个属性。对于 List 有可能出现跳空的情况,如页面只有索引不从 0 开始
         <s:textfield name="users[1].name" label="第二个用户名"/>
        <s:textfield name="users[1].name" label="第二个密码"/>
提交后就会发现,List 属性 users 的第一个元素为 null 了。同时如果尝试一下,你就会发现这里的 List 不能替代为数组 User[] users。 
    这种样法,可在 Struts 1 中实现,但要略施些小节,见我的另一篇日志:提交多行数据到Struts的ActionForm的List属性中 ,行为表现完全一致,只是换到 Struts 2 中一切都不用自己操心。

6. 看第四点,Action 之所以知道该构造什么类型的元素完全是由泛型告诉它的。如果不用泛型(比如用的是 JDK1.4),Action 中仅仅声明的是 Map users; 或 List users; Action 该如何处理呢?它也不知道,只能够帮你构造出无类型的 HashMap 和 ArrayList(),填充不了元素。这就必须在局部类型转换的配置文件中来指定集合元素的类型。例如 Action 为 LoginAction,就要在 LoginAction-conversion.properties 中声明了,格式如下:

    #Element_xxx=复合类型,基中 Element 是固定的,xxx 为属性名
    #下面表示为 List 属性 users 的元素为 com.unmi.vo.User 类型
     Element_users=com.unmi.vo.User

    对于 Map,须分别指定 Key 的类型和 Value 的类型
    #Key_xxx=复合类型,基中 Key 是固定的,xxx 为 map 属性名,下面写成 String 都不行的
    Key_users=java.lang.String
    指定 Map 的 Value 的类型与指定 List 元素类型是一样的
    Element_users=com.unmi.vo.User

难 怪 Struts 2 要与 1.5 以上 JDK  使用,泛型比配置来得方便。如果硬要用 1.4 JDK,就只有配置类型了,会多很多 conversion 文件的。在 提交多行数据到Struts的ActionForm的List属性中 中类型的确定由 AutoArrayList() 的构造参数完成。

7. Set 是无序集合,所以无法像 List 那样用数字下标来访问,幸好 Struts 2 可为其指定索引属性。例如,LoginAction 声明为 Set users; (这里好像用泛型只能省得了 Element_users 说明,KeyProperty_users 少不了)。则需在 LoginAction-conversion.properties 中写下:
    #指定 Set 的元素类型
    Element_users=com.unmi.vo.User

    #KeyProperty_集合属性名=集合元素的索引属性名,这里为 User 的 name 属性
    KeyProperty_users=name

此时提交页面这么写,最好提交前能根据输入的用户名自动修动输入框的 name。
        用户名: <input name="users('scott').name"/>
        密 码: <input name="users('scott').pass"/>
显示的时候页面可用标签
        用户名: <s:property value="users('scott').name"/>
        密 码: <s:property value="users('scott').pass"/>
注意前面,访问 Set 元素是用的圆括号,而不同于 Map、List、数组是用中括号。我想一般也犯不着非要用 Set 而不用 List,Struts 2 中用 Set 比在 Struts 1 中似乎还麻烦。

8. Struts 2 内建了一批转换器:boolean、char、int、long、float、double 和它们的包装类型;Date,日期格式使用请求所在 Locale 的 SHORT 格式;数组,默认元素为字符串,其他类型则要转换每一个元素?(好像是一次性转换完成的); 集合,默认元素为字符串 XWorkList(String.class, Object[]),其他如 List<Integer> ids,类型为 XWorkList(Integer.class, Object[]),XWorkList 继承自 ArrayList。

9. 类型转换出错由 Struts 来帮你处理,在默认拦截器栈中提供了 conversionError 拦截器,不用你写一点代码逻辑。conversionError 在出错时将错误封装成 fieldError,并放在 ActionContext 中。你所要做的就是遵循它的规则,1) 你的 Action 要继承自 ActionSupport,2)在 struts.xml 中声明名为 "input" 的 result,出错时会在 input 逻辑视图显示信息。3)尽量用标签来写输入域(如<s:textfield name="number" label="数量"/>),这样转换出错后,就会像校验失败一样把错误信息显示在每个输入框上面(视模板而定),否则要手工用 <s:fielderror/> 输出在某处。
默认时输出错误信息为(比如是属性 number,输入的是字符串时):Invalid field value for field "number".你可以改变默认显示,在全局国际化资源文件中加上xwork.default.invalid.fieldvalue={0}字段类型转换失败!。在某些时候,可能还需要对特定字段指定特别的提示信息,那么在名为 ActionName.properties 的局部资源文件中加上 invalid.fieldvalue.属性名=提示信息 (如 invalid.fieldvalue.number=数量格式错误)

10. 最后是集合属性转换错误时的显示,对于页面中的同名输入框,有多个出错误,如果手工用 <s:fieldError/> 只会显示一条错误,但要是输入页是用标签(如<s:textfield name="number" label="数量"/>),仍会在每一个出错的输入框上都提示。至此类型转换的内容也就完结了。

 

分享到:
评论

相关推荐

    struts2 类型转换器

    在Struts2中,类型转换器(Type Converter)是框架的一个关键特性,用于处理Action类中属性的自动类型转换。这个特性使得开发者无需手动进行数据类型之间的转换,从而提高了开发效率和代码的可读性。 标题中的...

    Struts2 自定类型转换器(三十四)

    要创建一个自定义的类型转换器,你需要实现`org.apache.struts2.convention.converters.Converter`接口或继承`org.apache.struts2.util.StrutsTypeConverter`类。`StrutsTypeConverter`类提供了很多便利方法,可以...

    struts2自定义类型转换器

    这就是"struts2自定义类型转换器"的主题。 首先,理解Struts2的类型转换机制。当Struts2接收到HTTP请求时,它会尝试将请求参数与Action类的属性进行绑定。这个过程涉及到了类型转换,Struts2内置了一套转换器机制,...

    struts2注册转换器

    Struts2框架提供了内置的转换器,可以处理基本类型和某些复杂类型的转换。然而,对于自定义格式或特殊需求,我们需要自定义转换器。转换器的实现基于`Converter`接口,该接口包含一个`convert`方法,用于执行实际的...

    Struts2之类型转换器的使用案例struts002

    本案例"Struts2之类型转换器的使用案例struts002"深入探讨了如何自定义类型转换器以及在实际应用中的使用。 首先,Struts2框架提供了一系列内置的类型转换器,可以自动处理基本类型和常见类型的数据转换,如String...

    struts2 转换器

    Struts2的转换器机制就是解决这个问题的关键,它允许我们自定义数据类型的转换过程,确保数据的准确性和一致性。 Struts2框架基于MVC设计模式,其中模型(Model)层处理业务逻辑,视图(View)层负责展示,控制器...

    Struts自定义类型转换器

    本文主要介绍Struts1和Struts2中的自定义类型转换器,并探讨其实现机制。 #### 二、Struts1中的自定义类型转换器 在Struts1中,自定义类型转换器主要是通过继承`com.sun.org.apache.commons.beanutils.Converter`...

    struts2简单实例(类型转换)

    Struts2框架提供了一种机制,即类型转换器(Type Converter),用于自动将请求参数转化为预期的数据类型。 在Struts2中,实现类型转换主要有两种方式: 1. 使用内置的类型转换器:Struts2已经内置了一些常见的类型...

    struts2 全局类型转换器.rar

    在Struts2中定义全局类型转换器,你需要创建一个实现`org.apache.struts2.conversion.Converter`接口的类,并在配置文件中声明。`.classpath`、`.mymetadata`、`.project`和`.myeclipse`这些文件是Eclipse或...

    struts2自定义数据类型转换练习

    创建自定义数据类型转换器需要实现`org.apache.struts2.util.TypeConverter`接口。这个接口包含了一个核心方法`convertValue()`,该方法负责将接收到的值转换为目标类型。我们还需要在类上添加`@Override`注解以确保...

    struts2学习笔记三(第3讲.Struts2的类型转换)

    Struts2内置了一些常见的类型转换器,如StringConverter、IntegerConverter、LongConverter等,可以处理基本类型的转换。如果这些内置转换器无法满足需求,开发者可以通过实现Converter接口自定义转换器。自定义转换...

    struts 2.0 自定义类型转换器 注册类型转换器 入门实例 简单实例

    自定义类型转换器是Struts 2的核心特性之一,允许开发者根据业务需求定制数据转换规则。以下将详细介绍如何创建、注册以及使用自定义类型转换器。 1. **创建自定义类型转换器** - 创建一个类,实现`org.apache....

    struts2的类型转换器授课教案和例子源码

    本授课教案和例子源码将深入探讨这一主题,帮助你更好地理解和应用Struts2的类型转换器。 在第一课时中,我们将首先了解Struts2类型转换的基本概念。Struts2框架默认提供了一些预定义的转换器,如将字符串转换为...

    Struts2 ConverterType类型转换 案例源码

    在这个案例中,我们将深入探讨Struts2中的ConverterType,以及如何实现一个自定义的类型转换器来处理坐标(x,y)的数据。 首先,了解Struts2的类型转换机制。默认情况下,Struts2会根据Action类中属性的数据类型...

    struts日期转换器

    要使用Struts的日期转换器,首先你需要在Action类中定义一个日期类型的属性,并为其添加相应的注解`@DateTimeFormat`,或者在Struts配置文件中定义一个转换器。`@DateTimeFormat`注解允许你指定日期的输入格式,这样...

    struts2类型转换 拦截器 校验的例子

    如果默认的转换器无法满足需求,开发者可以自定义转换器,通过实现`Converter`接口并注册到配置中,来实现特定类型的转换。 接下来,我们讨论**拦截器(Interceptor)**。拦截器是Struts2的核心组件之一,它允许在...

    struts2类型转换

    2. **Struts2类型转换器** Struts2的核心组件`ValueStack`负责管理Action对象,并使用`ConversionService`接口处理类型转换。默认情况下,Struts2提供了一系列内置的转换器,可以处理基本数据类型和一些常见的Java...

Global site tag (gtag.js) - Google Analytics