Struts2之类型转换器

时间:2017-1-11 11:11

——Struts2中提供的类型转换

在之前的Web项目中,可以使用BeanUtils直接将表单封装到JavaBean中(使用BeanUtils.populate()方法,将一个Map中的数据封装到对象中),用到了类型转换。

在Struts2中Action得到请求参数,也可以直接封装到JavaBean中。

Struts2内部提供大量类型转换器,用来完成数据类型转换问题:
    boolean 和 Boolean
    char 和 Character
    int 和 Integer
    long 和 Long
    float 和 Float
    double 和 Double
    Date:可以接收yyyy-MM-dd格式的字符串
    数组:可以将多个同名参数转换到数组中
    集合:支持将数据保存到List或者Map

    但是有时还需要自定义类型转换器:例如传递yyyy-MM-dd、yyyy年MM月dd日都可以,但是如果是yyyy/MM/dd就会出现问题。

关于Struts2中的类型转换器:
    Struts2类型转换器实际上都是基于OGNL实现的。
    Struts2中的类型转换器根接口是:
        com.opensymphony.xwork2.conversion.TypeConverter(选中类名按F4可以查看体系结构)

        图片


自定义类型转换器:

    1、步骤:
        1)创建一个类实现TypeConverter接口
        2)重写方法:convertValue(Map<String, Object> context, Object target, Member member, String propertyName, Object value, Class toType)
        3)注册类型转换器:使用XML文件

    2、详细说明:
        1)创建一个自定义类型转换器
            *   实现TypeConverter需要重写:
                convertValue(Map<String, Object> context, Object target, Member member, String propertyName, Object value, Class toType)

            *   但是参数太多,可以使用TypeConverter的子类:DefaultTypeConverter
                该类重写了父类的方法,参数变少了:
                    public Object convertValue(Map<String, Object> context, Object value, Class toType) {

                        return convertValue(value, toType);
                    }


            *   但是DefaultTypeConverter类只提供了“从页面获得字符串”的方法,并没有提供“向页面输出字符串”的方法,需要手动实现
                可以使用Type类的子类:StrutsTypeConverter
                优点:在这个类中将从页面接收的参数的封装以及从Action传递给页面的数据的封装进行了分离。
                    将DefaultTypeConverter类的:convertValue()方法分成了以下两个方法:
                        *   public abstract Object convertFromString(Map context, String[] values, Class toClass);
                            从页面获取到的数据。 

                        *   public abstract String convertToString(Map context, Object o);
                            传递给页面的数据。 

        2)怎样注册一个自定义类型转换器
            有三种注册方式,两种局部的,一种全局的。
            *   局部:针对Action
                >   将Action作为JavaBean,提供属性与get / set方法
                >   配置文件所在位置以及名称:在Action类所在包中,创建Action类名-conversion.properties
                >   配置文件书写格式:属性名称=类型转换器的完整类名
                >   birthday=com.wyc.utils.MyTypeConverter

            *   局部:针对JavaBean
                >   配置文件所在位置以及名称:在JavaBean类所在包中,创建JavaBean类名-conversion.properties
                >   配置文件书写格式:属性名称=类型转换器完整类名
                >   birhday=com.wyc.utils.MyTypeConverter

            *   全局:
                >   配置文件所在位置及名称:在src下创建一个xwork-conversion.properties
                >   配置文件书写格式:要转换的完整类型名称=类型转换器完整类名
                >   java.util.Date=com.wyc.utils.MyTypeConverter

注意:
    对于Struts2中的类型转换器,如果提交表单数据,向JavaBean中封装时出现问题,会报错:
        No result defined for action com.wyc.action.RegistAction and result input
    在result中没有定义input结果视图。

    如果配置了input视图,出现类型转换问题就会跳转到input指定的视图,否则抛出404错误。

    问题:为什么会跳转到input视图?
        因为Struts2中有如下几个拦截器(interceptor):
            *   <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
                如果Struts2的类型转换器执行类型转换时出现错误,该拦截器负责将对应错误信息封装成FieldError对象,并将这些错误信息放入ActionContext中。

            *   <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
                用于获取错误问题信息,向input视图跳转。

         如果是自定义类型转换器出现类型转换问题需要跳转到input视图,那么必须在类型转换器中抛出异常才可以,只有抛出异常,错误信息才会被StrutsConversionErrorInterceptor所捕获,用于处理。

        使用类型转换器中的错误处理,用户定义的Action必须继承ActionSupport。

        图片

    关于错误信息展示:
        需要使用Struts2框架提供的标签来展示。
        在页面中导入Struts2标签库然后使用:<s:fielderror />即可。


示例代码:自定义类型转换器

在src目录下创建配置文件:xwork-conversion.properties文件,在配置文件中添加:
    java.util.Date=com.wyc.utils.MyTypeConverter


public class MyTypeConverter extends StrutsTypeConverter {
 
    /*
     * 接收页面传递的数据,封装到JavaBean中
     */
    @Override
    public Object convertFromString(Map context, String[] values, Class toClass) {
        // System.out.println(context); // ognl.OgnlContext@faae24ad
        // System.out.println(values[0]); // [Ljava.lang.String;@29d90021
        // System.out.println(toClass); // class java.util.Date
 
        // 从表单获取到的数据是一个数组
        String value = values[0]; // 2016/10/10
        Date date = null;
        try {
            date = new SimpleDateFormat("yyyy/MM/dd").parse(value);
            return date;
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        return date;
    }
 
    @Override
    public String convertToString(Map context, Object o) {
        return null;
    }
}

——总结

1、Struts2中类型转换
    *   Struts2中类型转换器的根接口是TypeConerter
    *   Struts2中默认提供的类型转换
    *   自定义类型转换器
        >   怎样创建自定义类型转换器
            创建一个Action实现TypeConverter接口(或者继承DefaultTypeConverter、StrutsTypeConverter)
        >   怎样注册类型转换器
            局部:针对Action,文件名:ActionClassName-conversion.properties
                属性名=类型转换器全名
            全局:src下创建一个xwork-conversion.properties
                要转换类型的全名=类型转换器全名
        >   自定义类型转换器的问题 
原文地址:https://www.cnblogs.com/wwwwyc/p/6375419.html