Apache Commons Digester 三(规则注解)
前言
Digester规则的定义除了可以在代码中直接new规则添加到 Digester对象外,还可以用xml配置规则,如下所示:
<digester-rules>
<pattern value="*/foo">
<object-create-rule pattern="bar" classname="Foobar" />
<set-properties-rule pattern="bar" />
</pattern>
</digester-rules>
显然,xml的规则配置目前已经不是主流方法了,今后的大趋势肯定是用注解,所以本文将主要关注如何在javabean上使用注解来配置Digester规则;
Digester规则注解
简单描述下Digester 有哪几类注解,详细信息建议看api文档,其实也比较简单了,熟悉Digester规则的话,基本不用看也知道;
类型注解
- @ObjectCreate 绑定Digester的
ObjectCreateRule
规则 - @FactoryCreate 绑定Digester的FactoryCreateRule规则
属性注解
- @BeanPropertySetter
绑定Digester的
BeanPropertySetterRule
规则 - @SetProperty
绑定Digester的SetPropertiesRule规则
方法注解
- @CallMethod ----> org.apache.commons.digester3.CallMethodRule
- @SetNext ----> org.apache.commons.digester3.SetNextRule
- @SetRoot ----> org.apache.commons.digester3.SetRootRule
- @SetTop ----> org.apache.commons.digester3.SetTopRule
参数注解
- @CallParam ----> org.apache.commons.digester3.rule.CallParamRule
Digester注解例子
看了半天,可能也还没有清晰直观的认识,直接看个例子,基本也就差不多了
如下是我们要解析的xml文件:
<rss version="2.0">
<channel> <title>Apache</title>
<link>http://www.apache.org</link>
<description>The Apache Software Foundation</description>
<language>en-US</language>
<rating>(PICS-1.1 "http://www.rsac.org/ratingsv01.html"
2 gen true comment "RSACi North America Server"
for "http://www.rsac.org" on "1996.04.16T08:15-0500"
r (n 0 s 0 v 0 l 0))
</rating> <image>
<title>Apache</title>
<url>http://jakarta.apache.org/images/jakarta-logo.gif</url>
<link>http://jakarta.apache.org</link>
<width>505</width>
<height>480</height>
<description>The Jakarta project. Open source, serverside java.
</description>
</image> <item>
<title>Commons Attributes 2.1 Released</title>
<link>http://jakarta.apache.org/site/news/news-2004-2ndHalf.html#20040815.1
</link>
<description>The Apache Commons team is happy to announce the release
of Commons Attributes 2.1.
This is the first release of the new Commons-Attributes code.
</description>
</item> <item>
<title>Cloudscape Becomes Apache Derby</title>
<link>http://jakarta.apache.org/site/news/elsewhere-2004-2ndHalf.html#20040803.1
</link>
<description>IBM has submitted a proposal to the Apache DB project
for a Java-based package to be called 'Derby'.</description>
</item> <item>
<title>Commons BeanUtils 1.7 Released</title>
<link>http://jakarta.apache.org/site/news/news-2004-2ndHalf.html#20040802.1
</link>
<description />
</item> <item>
<title>Commons JXPath 1.2 Released</title>
<link>http://jakarta.apache.org/site/news/news-2004-2ndHalf.html#20040801.2
</link>
<description />
</item>
</channel>
</rss>
首先,观察分析要解析的xml文档,创建javabean对象,加上Digester元注解,
先创建一个Channel对象,如下所示,感觉也不需要过多解析,很直观了,注意下@SetNext注解,是根据方法参数对象里定义的注解匹配的
package apache.commons.digester3.example.annotations; import java.util.ArrayList;
import java.util.List; import org.apache.commons.digester3.annotations.rules.BeanPropertySetter;
import org.apache.commons.digester3.annotations.rules.ObjectCreate;
import org.apache.commons.digester3.annotations.rules.SetNext; /**
*
*
* @author http://www.cnblogs.com/chenpi/
* @version 2017年6月7日
*/
@ObjectCreate(pattern = "rss/channel")
public class Channel
{ private final List<Item> items = new ArrayList<Item>(); private Image image; @BeanPropertySetter(pattern = "rss/channel/title")
private String title; @BeanPropertySetter(pattern = "rss/channel/link")
private String link; @BeanPropertySetter(pattern = "rss/channel/description")
private String description; @BeanPropertySetter(pattern = "rss/channel/language")
private String language; @SetNext
public void setImage(Image image)
{
this.image = image;
} @SetNext
public void addItem(Item item)
{
this.items.add(item);
} /**
* @return the title
*/
public String getTitle()
{
return title;
} /**
* @param title the title to set
*/
public void setTitle(String title)
{
this.title = title;
} /**
* @return the link
*/
public String getLink()
{
return link;
} /**
* @param link the link to set
*/
public void setLink(String link)
{
this.link = link;
} /**
* @return the description
*/
public String getDescription()
{
return description;
} /**
* @param description the description to set
*/
public void setDescription(String description)
{
this.description = description;
} /**
* @return the language
*/
public String getLanguage()
{
return language;
} /**
* @param language the language to set
*/
public void setLanguage(String language)
{
this.language = language;
} /**
* @return the items
*/
public List<Item> getItems()
{
return items;
} /**
* @return the image
*/
public Image getImage()
{
return image;
} }
在定义两个对象Image和Item,如下所示,至此,我们就已经把xml中所有元素需要匹配的规则定义完了
package apache.commons.digester3.example.annotations; import org.apache.commons.digester3.annotations.rules.BeanPropertySetter;
import org.apache.commons.digester3.annotations.rules.ObjectCreate; /**
*
*
* @author http://www.cnblogs.com/chenpi/
* @version 2017年6月7日
*/
@ObjectCreate(pattern = "rss/channel/item")
public class Item
{ @BeanPropertySetter(pattern = "rss/channel/item/description")
private String description; @BeanPropertySetter(pattern = "rss/channel/item/link")
private String link; @BeanPropertySetter(pattern = "rss/channel/item/title")
private String title; /**
* @return the description
*/
public String getDescription()
{
return description;
} /**
* @param description the description to set
*/
public void setDescription(String description)
{
this.description = description;
} /**
* @return the link
*/
public String getLink()
{
return link;
} /**
* @param link the link to set
*/
public void setLink(String link)
{
this.link = link;
} /**
* @return the title
*/
public String getTitle()
{
return title;
} /**
* @param title the title to set
*/
public void setTitle(String title)
{
this.title = title;
} }
package apache.commons.digester3.example.annotations; import org.apache.commons.digester3.annotations.rules.BeanPropertySetter;
import org.apache.commons.digester3.annotations.rules.ObjectCreate; /**
*
*
* @author http://www.cnblogs.com/chenpi/
* @version 2017年6月7日
*/
@ObjectCreate(pattern = "rss/channel/image")
public class Image
{ @BeanPropertySetter(pattern = "rss/channel/image/description")
private String description; @BeanPropertySetter(pattern = "rss/channel/image/width")
private int width; @BeanPropertySetter(pattern = "rss/channel/image/height")
private int height; @BeanPropertySetter(pattern = "rss/channel/image/link")
private String link; @BeanPropertySetter(pattern = "rss/channel/image/title")
private String title; @BeanPropertySetter(pattern = "rss/channel/image/url")
private String url; /**
* @return the description
*/
public String getDescription()
{
return description;
} /**
* @param description the description to set
*/
public void setDescription(String description)
{
this.description = description;
} /**
* @return the width
*/
public int getWidth()
{
return width;
} /**
* @param width the width to set
*/
public void setWidth(int width)
{
this.width = width;
} /**
* @return the height
*/
public int getHeight()
{
return height;
} /**
* @param height the height to set
*/
public void setHeight(int height)
{
this.height = height;
} /**
* @return the link
*/
public String getLink()
{
return link;
} /**
* @param link the link to set
*/
public void setLink(String link)
{
this.link = link;
} /**
* @return the title
*/
public String getTitle()
{
return title;
} /**
* @param title the title to set
*/
public void setTitle(String title)
{
this.title = title;
} /**
* @return the url
*/
public String getUrl()
{
return url;
} /**
* @param url the url to set
*/
public void setUrl(String url)
{
this.url = url;
} // getters and setters }
规则与javabean绑定完后,就可以开始解析了,注意我们这里使用DigesterLoader来创建Digester实例对象,而DigesterLoader实例是通过FromAnnotationsRuleModule创建的,该类允许我们从一个注解的类上加载规则集:
/*
* File Name: Main.java
* Description:
* Author: http://www.cnblogs.com/chenpi/
* Create Date: 2017年6月7日
*/
package apache.commons.digester3.example.annotations; import org.apache.commons.digester3.Digester;
import org.apache.commons.digester3.annotations.FromAnnotationsRuleModule;
import org.apache.commons.digester3.binder.DigesterLoader; /**
*
* @author http://www.cnblogs.com/chenpi/
* @version 2017年6月7日
*/ public class Main
{
public static void main(String[] args)
{
try
{ DigesterLoader loader = DigesterLoader.newLoader(new FromAnnotationsRuleModule()
{
@Override
protected void configureRules()
{
bindRulesFrom(Channel.class);
} }); Digester digester = loader.newDigester(); Channel channel = digester
.parse(Main.class.getClassLoader().getResourceAsStream("rss.xml")); System.out.println(channel.getTitle());
System.out.println(channel.getImage().getDescription());
}
catch (Exception e)
{
e.printStackTrace();
} } }
结语
至此,Digester 的学习就告一段落了,除了使用xml定义规则(有注解了,感觉没必要在使用xml配置规则)和Digester插件模块(感觉很少会使用,不过参考代码里有例子)没详细说明外,基本涵盖了所有内容;
有兴趣的还可以深入研究,看看源码,相对而言也不难;
参考资料
http://commons.apache.org/proper/commons-digester/guide/annotations.html
参考代码
https://github.com/peterchenhdu/apache-commons-digester-example
Apache Commons Digester 三(规则注解)的更多相关文章
- Apache Commons Digester 二(规则模块绑定-RulesModule、异步解析-asyncParse、xml变量Substitutor、带参构造方法)
前言 上一篇对Digester做了基本介绍,也已经了解了Digester的基本使用方法,接下来将继续学习其相关特性,本篇主要涉及以下几个内容: 规则模块绑定,通过定义一个RulesModule接口实现 ...
- Apache Commons Digester 一 (基础内容、核心API)
前言 在许多需要处理XML格式数据的应用环境中, 如果能够以“事件驱动”的方式来处理XML文档,比如,当识别出特定的XML元素时,触发“创建对象”操作事件(或者触发调用对象的方法事件),这对于应用程序 ...
- NullPointerException org.apache.commons.digester.Digester.getXMLReader(Digester.java:1058)
http://pwu-developer.blogspot.com/2010/01/nullpointerexception.html Maven is great build tool making ...
- Apache Commons Beanutils 三 (BeanUtils、ConvertUtils、CollectionUtils...)
前言 前面已经学习了Apache Commons Beanutils包里的PropertyUtils和动态bean,接下来将学习剩下的几个工具类,个人觉得还是非常实用的,特别是CollectionUt ...
- Apache Commons 简述
Apache Commons 是一个关注于可复用的 Java 组件的 Apache 项目.Apache Commons 由三部分构成: Commons Proper - 一个可复用的 Java 组件库 ...
- Java (三)APACHE Commons IO 常规操作
上一篇:Java (二)基于Eclipse配置Commons IO的环境 例1:查看文件.文件夹的长度(大小). 1 import java.io.File; 2 3 import org.apach ...
- apache commons Java包简介
更多信息,请参考:http://commons.apache.org/ 一.Commons BeanUtils说明:针对Bean的一个工具集.由于Bean往往是有一堆get和set组成,所以BeanU ...
- 一篇关于apache commons类库的详解
1.1. 开篇 在Java的世界,有很多(成千上万)开源的框架,有成功的,也有不那么成功的,有声名显赫的,也有默默无闻的.在我看来,成功而默默无闻的那些框架值得我们格外的尊敬和关注,Jakarta C ...
- 一篇关于apache commons类库的详解[转]
1.1. 开篇 在Java的世界,有很多(成千上万)开源的框架,有成功的,也有不那么成功的,有声名显赫的,也有默默无闻的.在我看来,成功而默默无闻的那些框架值得我们格外的尊敬和关注,Jakarta C ...
随机推荐
- git回滚远程仓库
关于远程仓库回滚 首先,必须要明白的一件事,任何普通用户不能擅自做有关远程仓库回退的操作,如果你擅自回滚了远程仓库,会对项目团队其他人造成不可预知的影响.如果需要回退版本,先联系项目的仓库管理员,在团 ...
- webapi postman 415 错误
https://blog.csdn.net/Intangible_moon/article/details/80183121 猜测:如果后台接口使用的是[fromBody]标签的话,需要使用raw方式
- Py西游攻关之RabbitMQ、Memcache、Redis
Py西游攻关之RabbitMQ.Memcache.Redis RabbitMQ 解释RabbitMQ,就不得不提到AMQP(Advanced Message Queuing Protocol)协议 ...
- PHP开发——函数
函数的定义 l 函数是一段命名的代码段. 函数可以减轻工作量,减少重复的代码,方便后期维护. 函数的参数 l 实参:调用函数时,传递的参数就是实参,含有真正数据的. l 形参:定义函数时的参数. ...
- Python开发——函数【迭代器、生成器、三元表达式、列表解析】
递归和迭代 小明问路篇解释说明 递归:小明——>小红——>小于——>小东:小东——>小于——>小红——>小明 小明向小红问路,因小红不知道,所以向小于问路,因小于不 ...
- Spring 框架下 事务的配置(复杂)
//db.properties配置 src下的文件 jdbc.jdbcUrl=jdbc:mysql:///day43jdbc.driverClass=com.mysql.jdbc.Driverjdb ...
- netty随笔
netty是一个nio框架,通过rpc长连接进行通信. nio和bio的区别是:bio是通过tcp/ip的三次握手机制实现通信,服务端连接几个客户端就要开几个线程,而nio有一个叫选择器(多路复用器) ...
- XML文件的DTD编写
<?xml version="1.0" encoding="UTF-8" ?> <!--DTD外部引用:--> <!DOCTYPE ...
- margin和padding的用法与区别--以及bug处理方式
margin和padding的用法: (1)padding (margin) -left:10px; 左内 (外) 边距(2)padding (margin) -right:10px; 右内 (外 ...
- UML类图中箭头和线条的含义和用法
UML类图中箭头和线条的含义和用法 在学习UML过程中,你经常会遇到UML类图关系,这里就向大家介绍一下UML箭头.线条代表的意义,相信通过本文的介绍你对UML中箭头.线条的意义有更明确的认识. AD ...