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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM