CMS项目总结:11、BeanUtils工具的使用

由于在原来的ArticleServlet中当添加新文章或者更新原来的文章时,会存在大量的从add_article.jsp或者update_article.jsp中传递过来的参数,然后将这些参数设置到Article这个Bean中,然后再把这个Bean传到DAO中根据Bean的属性往数据库的table插数据。

CMS项目总结:11、BeanUtils工具的使用_第1张图片

table(对应Bean)的字段太多(属性太多)时,不停的String title = request.getParameter("title");……然后再:Article a = new Article(); a.setTitle(title);……是个很繁琐的过程。所以我们使用apache-commons-beanutils这个工具来简化代码,继续封装。

1、简化后的ArticleServletadd()方法为:

CMS项目总结:11、BeanUtils工具的使用_第2张图片

2具体的实现封装在RequestUtil类中:

CMS项目总结:11、BeanUtils工具的使用_第3张图片

在RequestUtil中就进入重点了:

ArticleServlet中是这么调用RequestUtil的:Article a = (Article)RequestUtil.copyParam(Article.class, request);request直接传入RequestUtil中(request是从add_article中传过来的,包含了Article这个Bean的各种属性)。在RequestUtil中首先new出一个Article的实例:Object entity = entityClass.newInstance();(在接下来的代码中给Article的属性各种赋值,最后再将这个Article returnArticleServlet中,ArticleServlet再将Article传给DAO,进行插入数据库的过程)。

Map allParams = request.getParameterMap();

Set entries = allParams.entrySet();

for (Iterator iterator = entries.iterator(); iterator.hasNext();) {

Map.Entry entry = (Map.Entry) iterator.next();

String name = (String)entry.getKey();

String[] value = (String[])entry.getValue();     //以上这段代码是从request中取出所有的数据。nameArticle的属性名,而value即是属性值了。注意valueString【】类型的

if(value != null){

if(value.length == 1){

BeanUtils.copyProperty(entity, name, value[0]);

}else{

BeanUtils.copyProperty(entity, name, value);

}

}

(接下来先分析简单的BeanUtils功能:

Article a = new Article();

BeanUtils.copyProperty(a, "title""这是标题");

BeanUtils.copyProperty(a, "leaveNumber""30");

BeanUtils.copyProperty(a, "recommend""true");

这些话的意思是:将第三个参数赋值给第一个参数里的第二个属性(将"这是标题"赋值给a这个Article的title属性)

title是String类型,"这是标题"是String类型,而leaveNumberint类型的,"30"是String类型的,recommendboolean类型,"true"String类型的,可以看出BeanUtils可以在一定范围内自动的将String转换为int、boolean、……类型赋值给对应的属性。)

1、name普通的属性譬如titlesourceclickNumber这些Stringint…类型,且传递过来的value是长度为1String【】时,调用BeanUtils.copyProperty(entity, name, value[0]);

2、name普通的属性譬如titlesource这些Stringint…类型,且传递过来的value是长度不为1String【】时,调用BeanUtils.copyProperty(entity, name, value);

3、当name为channels这种Set(List……)类型的属性时,BeanUtils.copyProperty是不能自动的将长度为1String【】(即String)或者长度不为1String【】类型的值copySetList……)中的,得自己定义类型转换器。这样在以后调用BeanUtils.copyProperty()方法时,如果发现name的属性为类型转换器注册的属性(此例为Set),则不执行默认的BeanUtils.copyProperty而是执行类型转换器,将类型转换器的返回值即一个Set赋值给name属性。

ChannelsSetConverter(类型转换器)的代码:

CMS项目总结:11、BeanUtils工具的使用_第4张图片

首先ChannelsSetConverter实现了Converter接口,Converter接口中只有一个convert()方法,现在ChannelsSetConverter来重写这个方法,第一个参数Class targetClass表示目标类型,即BeanUtils.copyProperty(entity, name, value);中的name的类型(在这个例子中namechannels,它的类型为Set),第二个参数 Object valueBeanUtils.copyProperty(entity, name, value);中的value在注册ConvertUtils.register(new ChannelsSetConverter(), Set.class);后,当调用BeanUtils.copyProperty(Object bean, String  name, Object value);这句时,如果name的属性跟注册ChannelsSetConverter时的Set类型一致的话,不通过自动转换来给name赋值,而是调用ChannelsSetConverter类型转换器,用户自定义后在将返回值返回给BeanUtils.copyProperty(entity, name, value)中的name属性。

如果在add_article.jsp页面中添加文章时只选择了一个channel,那么value即是String,如果文章选择了多个channel,则valueString【】,我们统一都转换为String【】,注意String是不能强制类型转换,需要channelIds = new String[]{(String)value};add_article.jsp页面中传递过来的是channelid组成的String【】

CMS项目总结:11、BeanUtils工具的使用_第5张图片

接下来根据id参数设置channels,返回回去赋值给Article中的channels

接下来就要注册ChannelsSetConverter类型转换器,注册应该是全局性的,将它放到统一的入口地方InitBeanFactoryServlettomcat启动时候首先调用的servlet,因为在web.xml<load-on-startup>0</load-on-startup>

CMS项目总结:11、BeanUtils工具的使用_第6张图片

 

你可能感兴趣的:(DAO,bean,数据库,String,servlet,工具)