论坛首页 Java企业应用论坛

动态properties转换

浏览 31987 次
该帖已经被评为精华帖
作者 正文
   发表时间:2008-05-08  
armorking 写道
ajoo 写道
bottom 写道
BeanUtils.copyProperties(foo, map);

这个,不管在必须的property不存在的情况下报错吧?而且,BeanUtils是1.5以前的吧?管enum么?


BeanUtils与ConvertUtilsBean都是“org.apache.commons.beanutils ”提供的
而且BeanUtils.copyProperties方法正是用ConvertUtilsBean实现的类型转换
如果BeanUtils搞不定enum的话,ConvertUtilsBean就可以了么?

ConvertUtilsBean和enum或者jdk1.5没有任何关系的,不就是进行enum转换嘛,你写个EnumConverter注册到ConvertUtilsBean就行了。
0 请登录后投票
   发表时间:2008-05-08  
myyate 写道
armorking 写道
ajoo 写道
bottom 写道
BeanUtils.copyProperties(foo, map);

这个,不管在必须的property不存在的情况下报错吧?而且,BeanUtils是1.5以前的吧?管enum么?


BeanUtils与ConvertUtilsBean都是“org.apache.commons.beanutils ”提供的
而且BeanUtils.copyProperties方法正是用ConvertUtilsBean实现的类型转换
如果BeanUtils搞不定enum的话,ConvertUtilsBean就可以了么?

ConvertUtilsBean和enum或者jdk1.5没有任何关系的,不就是进行enum转换嘛,你写个EnumConverter注册到ConvertUtilsBean就行了。


Converter接口的convert方法签名如下:
    public Object convert(Class type, Object value);


而Enum的valueOf方法签名如下:
public static <T extends Enum<T>> T valueOf(Class<T> enumType,
                                            String name);



我没用过JDK1.5,手边也没有合适的环境
所以,我想问一下:这个基于范型的EnumConverter类真的能实现么?
0 请登录后投票
   发表时间:2008-05-08  
引用
很优雅,很有创意,改进了两点
1.能够自动为基本类型赋默认值,比如 int id();不用写成 int id() default 0,还有支持enum类型转化;

原始的需求是所有的域都是缺省强制的,如果map里面没有是要抛异常的。所以不能自动提供默认值。enum本来就是支持的,只要自己在converter bean里面注册一个enum converter就是了。ConvertUtils不能直接用,它对非法字符串保持沉默而不抛异常。所以要自己用ConvertUtilsBean。


引用
2.支持getter,方便jstl,ognl之类的表达式, name()和getName()是一样的

哦,在annotation里,没有getName()这个命名规范的。不用操心的吧?

其实,可以另外弄一个annotation来处理key的名字和方法名不匹配的情况:

@Rentention(RUNTIME)
@Target(METHOD)
@interface Property {
  String value();
}

@interface Foo {
  @Property("标识符")
  int id();
  String name() default "";
}
0 请登录后投票
   发表时间:2008-05-08  
myyate 写道
armorking 写道
ajoo 写道
bottom 写道
BeanUtils.copyProperties(foo, map);

这个,不管在必须的property不存在的情况下报错吧?而且,BeanUtils是1.5以前的吧?管enum么?


BeanUtils与ConvertUtilsBean都是“org.apache.commons.beanutils ”提供的
而且BeanUtils.copyProperties方法正是用ConvertUtilsBean实现的类型转换
如果BeanUtils搞不定enum的话,ConvertUtilsBean就可以了么?

ConvertUtilsBean和enum或者jdk1.5没有任何关系的,不就是进行enum转换嘛,你写个EnumConverter注册到ConvertUtilsBean就行了。

convert()函数就是这么用的。问题是,BeanUtils.copyProperties()能自动使用我的enum converter么?还有报错怎么解决?
0 请登录后投票
   发表时间:2008-05-09  
ajoo 写道
引用
很优雅,很有创意,改进了两点
1.能够自动为基本类型赋默认值,比如 int id();不用写成 int id() default 0,还有支持enum类型转化;

原始的需求是所有的域都是缺省强制的,如果map里面没有是要抛异常的。所以不能自动提供默认值。enum本来就是支持的,只要自己在converter bean里面注册一个enum converter就是了。ConvertUtils不能直接用,它对非法字符串保持沉默而不抛异常。所以要自己用ConvertUtilsBean。


引用
2.支持getter,方便jstl,ognl之类的表达式, name()和getName()是一样的

哦,在annotation里,没有getName()这个命名规范的。不用操心的吧?

其实,可以另外弄一个annotation来处理key的名字和方法名不匹配的情况:

@Rentention(RUNTIME)
@Target(METHOD)
@interface Property {
  String value();
}

@interface Foo {
  @Property("标识符")
  int id();
  String name() default "";
}

1.需要手动注册enum converter还不如直接写在这个里面,也就是两行代码
2.在annotation里面增加getName()是为了能够在EL里面可以用xxx.name

还有这个@Property("标识符")起什么作用?也不能用EL在UI上面显示出来.
0 请登录后投票
   发表时间:2008-05-09  
quaff 写道
ajoo 写道
引用
很优雅,很有创意,改进了两点
1.能够自动为基本类型赋默认值,比如 int id();不用写成 int id() default 0,还有支持enum类型转化;

原始的需求是所有的域都是缺省强制的,如果map里面没有是要抛异常的。所以不能自动提供默认值。enum本来就是支持的,只要自己在converter bean里面注册一个enum converter就是了。ConvertUtils不能直接用,它对非法字符串保持沉默而不抛异常。所以要自己用ConvertUtilsBean。


引用
2.支持getter,方便jstl,ognl之类的表达式, name()和getName()是一样的

哦,在annotation里,没有getName()这个命名规范的。不用操心的吧?

其实,可以另外弄一个annotation来处理key的名字和方法名不匹配的情况:

@Rentention(RUNTIME)
@Target(METHOD)
@interface Property {
  String value();
}

@interface Foo {
  @Property("标识符")
  int id();
  String name() default "";
}

1.需要手动注册enum converter还不如直接写在这个里面,也就是两行代码
2.在annotation里面增加getName()是为了能够在EL里面可以用xxx.name

还有这个@Property("标识符")起什么作用?也不能用EL在UI上面显示出来.


怎么转换enum就是具体实现方法了。我是因为有一个单独可重用的ConvertUtilsBean负责转换所有类型,所以直接拿过来用了,你自己写也可以的。

至于@Property么,用来处理你的Map里面的key和方法名不能匹配的情况,比如例子里面Map的key是“老婆,出来看标识符”,你总不能把方法名字也写这么一大长串吧?(除非你是中文编程的扇子)。ui么,呵呵,俺不知道。这个ui不能被定制的么?
0 请登录后投票
   发表时间:2008-05-09  
ajoo 写道
主要是这个默认值,除了annotation想不到别的好办法解决。

别的人也给了些建议,比如自己写一个Property<T>类,在这个类里面实现类型转换和默认值处理。不过都要求比较多的代码,而且用起来客户代码还要依赖于一个不是很容易mock的Property类。反而不如动态代理简单干净,侵入性基本没有。用起来可以注射进一个接口,而不是PropertyConverter类,这样最容易测试。

你要用随便啦。反正都贴在blog里了,随便拷贝。


我比较笨,想不出来为什么写一个类负责转换会要求更多的代码,如下(木有写过 java,语法错误莫怪):

public abstract class Base
{
    private final Map<String, String> _map;
    public Base(Map<String, String> map) { _map = map; }
    public T GetProperty<T>(String key, T defaultValue)
    {
        String value = _map.get(key);
        if (value == null) {
            if (defaultValue == null) {
                throw ...;
            }
            return defaultValue;
        }
        return convert(value);
    }
}

public final class Foo : Base
{
    public Foo(Map<String, String> map) : base(map) {}

    public int id() { return Base.GetProperty<int>("id", null); }
    public String name() { return Base.GetProperty<String>("name", ""); }
    Gender sex() { return Base.GetProperty<Gender>("sex", null); }  
}
   
Map<String, String> map = ...;
Foo foo = new Foo(map);
foo.id();
foo.name();


当然啦,这个看起来木有你原来那个帅,不过相对而言要好懂一些吧?而且处理方法名和属性名不同的情况也不用额外多费手脚了。
0 请登录后投票
   发表时间:2008-05-09  
ajoo 写道
quaff 写道
ajoo 写道
引用
很优雅,很有创意,改进了两点
1.能够自动为基本类型赋默认值,比如 int id();不用写成 int id() default 0,还有支持enum类型转化;

原始的需求是所有的域都是缺省强制的,如果map里面没有是要抛异常的。所以不能自动提供默认值。enum本来就是支持的,只要自己在converter bean里面注册一个enum converter就是了。ConvertUtils不能直接用,它对非法字符串保持沉默而不抛异常。所以要自己用ConvertUtilsBean。


引用
2.支持getter,方便jstl,ognl之类的表达式, name()和getName()是一样的

哦,在annotation里,没有getName()这个命名规范的。不用操心的吧?

其实,可以另外弄一个annotation来处理key的名字和方法名不匹配的情况:

@Rentention(RUNTIME)
@Target(METHOD)
@interface Property {
  String value();
}

@interface Foo {
  @Property("标识符")
  int id();
  String name() default "";
}

1.需要手动注册enum converter还不如直接写在这个里面,也就是两行代码
2.在annotation里面增加getName()是为了能够在EL里面可以用xxx.name

还有这个@Property("标识符")起什么作用?也不能用EL在UI上面显示出来.


怎么转换enum就是具体实现方法了。我是因为有一个单独可重用的ConvertUtilsBean负责转换所有类型,所以直接拿过来用了,你自己写也可以的。

至于@Property么,用来处理你的Map里面的key和方法名不能匹配的情况,比如例子里面Map的key是“老婆,出来看标识符”,你总不能把方法名字也写这么一大长串吧?(除非你是中文编程的扇子)。ui么,呵呵,俺不知道。这个ui不能被定制的么?

叫@Alias更好一些,我以为你把它当label显示在UI上面,UI上面一般都是用EL来获取值,如果你要在UI里面写java代码也没说不可以.
0 请登录后投票
   发表时间:2008-05-09  
Elminster 写道
ajoo 写道
主要是这个默认值,除了annotation想不到别的好办法解决。

别的人也给了些建议,比如自己写一个Property<T>类,在这个类里面实现类型转换和默认值处理。不过都要求比较多的代码,而且用起来客户代码还要依赖于一个不是很容易mock的Property类。反而不如动态代理简单干净,侵入性基本没有。用起来可以注射进一个接口,而不是PropertyConverter类,这样最容易测试。

你要用随便啦。反正都贴在blog里了,随便拷贝。


我比较笨,想不出来为什么写一个类负责转换会要求更多的代码,如下(木有写过 java,语法错误莫怪):

public abstract class Base
{
    private final Map<String, String> _map;
    public Base(Map<String, String> map) { _map = map; }
    public T GetProperty<T>(String key, T defaultValue)
    {
        String value = _map.get(key);
        if (value == null) {
            if (defaultValue == null) {
                throw ...;
            }
            return defaultValue;
        }
        return convert(value);
    }
}

public final class Foo : Base
{
    public Foo(Map<String, String> map) : base(map) {}

    public int id() { return Base.GetProperty<int>("id", null); }
    public String name() { return Base.GetProperty<String>("name", ""); }
    Gender sex() { return Base.GetProperty<Gender>("sex", null); }  
}
   
Map<String, String> map = ...;
Foo foo = new Foo(map);
foo.id();
foo.name();


当然啦,这个看起来木有你原来那个帅,不过相对而言要好懂一些吧?而且处理方法名和属性名不同的情况也不用额外多费手脚了。

这种代码差不多所有人都会写,还不如GetProperty做成静态方法然后引入,还去掉了必须继承Base这个限制
0 请登录后投票
   发表时间:2008-05-09  

怎么回事?javaeye bug?删除

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics