• 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

  • 相关阅读:
    使用json序列化类型为“ajax学习.DataSetComment+T_CommentDataTable”的对象时检测到循环引用。
    CKEditor在asp.net上使用的图例详解
    去掉 win7 “测试模式 windows7 内部版本7601” 字样
    Java中非静态方法是否共用同一块内存?
    最长公共子串(LCS)
    [链表]复杂链表的复制
    最长公共子序列
    最大子序列和问题
    [ 队列]从上往下遍历二元树
    [链表]在O(1)时间删除链表结点
  • 原文地址:https://www.cnblogs.com/chenpi/p/6959691.html
Copyright © 2020-2023  润新知