前言

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 三(规则注解)的更多相关文章

  1. Apache Commons Digester 二(规则模块绑定-RulesModule、异步解析-asyncParse、xml变量Substitutor、带参构造方法)

    前言 上一篇对Digester做了基本介绍,也已经了解了Digester的基本使用方法,接下来将继续学习其相关特性,本篇主要涉及以下几个内容: 规则模块绑定,通过定义一个RulesModule接口实现 ...

  2. Apache Commons Digester 一 (基础内容、核心API)

    前言 在许多需要处理XML格式数据的应用环境中, 如果能够以“事件驱动”的方式来处理XML文档,比如,当识别出特定的XML元素时,触发“创建对象”操作事件(或者触发调用对象的方法事件),这对于应用程序 ...

  3. 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 ...

  4. Apache Commons Beanutils 三 (BeanUtils、ConvertUtils、CollectionUtils...)

    前言 前面已经学习了Apache Commons Beanutils包里的PropertyUtils和动态bean,接下来将学习剩下的几个工具类,个人觉得还是非常实用的,特别是CollectionUt ...

  5. Apache Commons 简述

    Apache Commons 是一个关注于可复用的 Java 组件的 Apache 项目.Apache Commons 由三部分构成: Commons Proper - 一个可复用的 Java 组件库 ...

  6. Java (三)APACHE Commons IO 常规操作

    上一篇:Java (二)基于Eclipse配置Commons IO的环境 例1:查看文件.文件夹的长度(大小). 1 import java.io.File; 2 3 import org.apach ...

  7. apache commons Java包简介

    更多信息,请参考:http://commons.apache.org/ 一.Commons BeanUtils说明:针对Bean的一个工具集.由于Bean往往是有一堆get和set组成,所以BeanU ...

  8. 一篇关于apache commons类库的详解

    1.1. 开篇 在Java的世界,有很多(成千上万)开源的框架,有成功的,也有不那么成功的,有声名显赫的,也有默默无闻的.在我看来,成功而默默无闻的那些框架值得我们格外的尊敬和关注,Jakarta C ...

  9. 一篇关于apache commons类库的详解[转]

    1.1. 开篇 在Java的世界,有很多(成千上万)开源的框架,有成功的,也有不那么成功的,有声名显赫的,也有默默无闻的.在我看来,成功而默默无闻的那些框架值得我们格外的尊敬和关注,Jakarta C ...

随机推荐

  1. Python学习积累:使用help();打印多个变量;fileno()

    1.使用篇: 1.1如何从help()退出: 直接回车即可! 2.技能篇: 2.1 如何一次性打印多个变量? 多个变量中间使用逗号隔开,且引用变量为%(变量1,变量2,变量3), 2.2fileno( ...

  2. Sass入门及知识点整理

    Sass 快速入门 | SASS 中文网 文档链接:https://www.sasscss.com/getting-started/ 前言 之前整理了一篇关于Less的,现在就来整理一下关于Sass的 ...

  3. go语言 http学习

    net/http库学习 概念 处理器 处理器:拥有ServeHTTP方法的接口(任何类型) 签名:ServeHTTP(http.ResponseWriter, *http.Request) Respo ...

  4. Android开发之页面跳转传递list集合

    这篇随笔这里详细记录两个activity之间如何传递list集合中的数据. 1.首先要对javabean进行序列化处理,即实现Serializable. package com.anhua.bean; ...

  5. 面试01:解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法

    栈的使用:通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用JVM中的栈空间. 队的使用:通过new关键字和构造器创建的对象则放在堆空间,堆是垃圾收集器管理的主要区域 ...

  6. Django跨域(前端跨域)

    前情回顾 在说今天的问题之前先来回顾一下有关Ajax的相关内容 Ajax的优缺点 AJAX使用Javascript技术向服务器发送异步请求: AJAX无须刷新整个页面: 因为服务器响应内容不再是整个页 ...

  7. 游戏脚本编程 文本token解析

    一个数字的组成由以下几个字符 正负号 + -   小数点 .   数字 0-9 比如 3 -3 3.13 -34.2234 但是符号和小数点不会出现多次 那么识别流程用图来表示 则是 整数 浮点数 一 ...

  8. win10自带输入法的标点符号切换

    快捷键是ctrl+句号 然后开启设置,把中文也用英文标点也选上.

  9. 获取sql 时间时分秒

    select DATE_FORMAT(now(),'%Y-%m-%d %T') from dual;  年月日时分秒 select DATE_FORMAT(now(),'%T') from dual; ...

  10. Solidity合约记录——(三)如何在合约中对操作进行权限控制

    合约中一般会有多种针对不同数据的操作:例如对于存证内容的增加.更新及查询,若不进行一套符合要求的权限控制,事实上整个合约在真实环境下是没有多少使用价值的.那么应当如何对合约的权限进行划分?我们针对So ...