Статьи

Пример Apache Digester — Простая настройка

Решение проблемы — жесткое программирование, необходимо создать пользовательскую конфигурацию для вашего приложения, например файл конфигурации Struts, чтобы изменить поведение приложения, просто изменив файл. Apache Digester может сделать это для вас легко.

Преобразование XML-документа в соответствующую иерархию объектов Java-бина довольно просто с помощью Apache Digester. См. Дигестер в действии ниже.
Дигестер вводит три важных понятия:

  1. шаблоны соответствия элементов
  2. правила обработки
  3. стек объектов.

Шаблоны сопоставления элементов связывают элементы XML с правилами обработки.

Пример :
Что у тебя есть:

  1. Java классы
  2. XML-файлы, содержащие данные

У вас есть классы Java и соответствующие файлы XML. Вы хотите, чтобы экземпляры классов Java создавались из данных XML.

Какой дополнительный код вам нужно написать.
Пошаговые задания:

  1. Добавьте Apar Digester 3 jar file, банку регистрации Commons, банку Beanutils, банку cglib в вашем классе
  2. Если у вас нет java-классов, создайте java-классы для соответствующего XML-файла. Или, если у вас нет xml-файлов, создайте его в соответствии с java-классами. необходимо обеспечить сопоставление в вашем правиле xml метки, не упомянутом здесь.
  3. Создайте xml-файл правила метантенка, как указано в примере ниже
  4. Используйте несколько строк для загрузки Java-объектов из XML

Сейчас в действии —

Вот моя структура проекта затмения:

Задача 2создайте файл данных XML, как показано ниже, для которого вы хотите загрузить данные, скажем — chain-config.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?xml version="1.0" encoding="UTF-8"?>
 
<catalogs>
 
    <!-- Default Catalog: "Path Info" example -->
    <catalog>
 
        <!-- Command that maps "Path Info" patterns to Commands -->
        <chain name="COMMAND_MAPPER">
            <command                       className="org.apache.commons.chain.web.servlet.PathInfoMapper"/>
            <command forward="/pathinfo.jsp"  className="org.apache.commons.chain.apps.example.ForwardCommand"/>
        </chain>
 
        <!-- Foo Command -->
        <chain name="/foo">
            <command attribute="pathinfoFooCount" className="org.apache.commons.chain.apps.example.CountCommand"/>
        </chain>
 
        <!-- Bar Command -->
        <chain name="/bar">
            <command attribute="pathinfoBarCount" className="org.apache.commons.chain.apps.example.CountCommand"/>
        </chain>
 
    </catalog>
 
    <!-- Catalog for "Request Parameter" example -->
    <catalog name="reqparam">
 
        <!-- Command that maps a "Request Parameter" to Commands -->
        <chain name="COMMAND_MAPPER">
            <command catalogName="reqparam"  className="org.apache.commons.chain.web.servlet.RequestParameterMapper"/>
            <command forward="/reqparam.jsp" className="org.apache.commons.chain.apps.example.ForwardCommand"/>
        </chain>
 
        <!-- Foo Command -->
        <chain name="foo">
            <command attribute="reqparamFooCount" className="org.apache.commons.chain.apps.example.CountCommand"/>
        </chain>
 
        <!-- Bar Command -->
        <chain name="bar">
            <command attribute="reqparamBarCount" className="org.apache.commons.chain.apps.example.CountCommand"/>
        </chain>
 
    </catalog>
 
</catalogs>


Создайте соответствующие классы java Catalog.java:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.util.ArrayList;
import java.util.List;
 
 
 
public class Catalog {
 
    /**
     * @uml.property  name="name"
     */
    private String name;
 
    /**
     * Getter of the property <tt>name</tt>
     * @return  Returns the name.
     * @uml.property  name="name"
     */
    public String getName() {
        return name;
    }
 
    /**
     * Setter of the property <tt>name</tt>
     * @param name  The name to set.
     * @uml.property  name="name"
     */
    public void setName(String name) {
        this.name = name;
    }
 
    /**
     * @uml.property  name="chains"
     */
     
    private List<Chain> chains=new ArrayList<Chain>();
     
    public void addChains(Chain chain)
    {
        this.chains.add(chain);
    }
 
}


Chain.java:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import java.util.ArrayList;
import java.util.List;
 
 
 
public class Chain {
 
    /**
     * @uml.property  name="name"
     */
    private String name;
 
    /**
     * Getter of the property <tt>name</tt>
     * @return  Returns the name.
     * @uml.property  name="name"
     */
    public String getName() {
        return name;
    }
 
    /**
     * Setter of the property <tt>name</tt>
     * @param name  The name to set.
     * @uml.property  name="name"
     */
    public void setName(String name) {
        this.name = name;
    }
 
    /**
     * @uml.property  name="commands"
     */
    private List<Command> commands=new ArrayList<Command>();
     
 
    /**
     * Setter of the property <tt>commands</tt>
     * @param commands  The commands to set.
     * @uml.property  name="commands"
     */
    public void addCommands(Command command) {
        this.commands.add(command);
    }
 
}


Command.java:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.util.ArrayList;
import java.util.List;
 
 
 
public class Chain {
 
    /**
     * @uml.property  name="name"
     */
    private String name;
 
    /**
     * Getter of the property <tt>name</tt>
     * @return  Returns the name.
     * @uml.property  name="name"
     */
    public String getName() {
        return name;
    }
 
    /**
     * Setter of the property <tt>name</tt>
     * @param name  The name to set.
     * @uml.property  name="name"
     */
    public void setName(String name) {
        this.name = name;
    }
 
    /**
     * @uml.property  name="commands"
     */
    private List<Command> commands=new ArrayList<Command>();
     
    /**
     * Getter of the property <tt>commands</tt>
     * @return  Returns the commands.
     * @uml.property  name="commands"
     */
    public List getCommands() {
        return commands;
    }
 
    /**
     * Setter of the property <tt>commands</tt>
     * @param commands  The commands to set.
     * @uml.property  name="commands"
     */
    public void addCommands(Command command) {
        this.commands.add(command);
    }
 
}

Задача 3 — Создание правил метантенка digester-catalog-rules.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?xml version="1.0"?>
<!DOCTYPE digester-rules PUBLIC
  "-//Apache Commons //DTD digester-rules XML V1.0//EN"
<digester-rules>
 
  <pattern value="catalogs/catalog">
 
    <object-create-rule classname="Catalog"/>
 
 
 
    <set-properties-rule/>
 
   <!-- comment :
 
  <bean-property-setter-rule pattern="name"/> 
 
use as shown above  if say  <catalog><name>reparam</name> </catalog> instead of <catalog name="reparam"> </catalog>
 
-->
 
 
     
 
    <!-- Nested Pattern for Characters -->
 
    <pattern value="chain">
 
      <object-create-rule classname="Chain"/>
 
 
      <set-properties-rule/>                
                      
 
 <!-- Nested Pattern for Characters -->
                             <pattern value="command">
 
      <object-create-rule classname="Command"/>
 
 
                           <set-properties-rule/>
 
                          <set-next-rule methodname="addCommands"  paramtype="Command"/>
</pattern>
      <set-next-rule methodname="addChains" paramtype="Chain"/>
</pattern>
    <set-next-rule methodname="add" paramtype="Catalog"/>
</pattern>
</digester-rules>

Задача 4 — Клиентская программа для загрузки XML-данных

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
 
import org.apache.commons.digester3.Digester;
import org.apache.commons.digester3.binder.DigesterLoader;
import org.apache.commons.digester3.xmlrules.FromXmlRulesModule;
import org.xml.sax.SAXException;
 
import java.util.ArrayList;
import java.util.List;
 
public class runProgram {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
 
         
        // Create an instance of the Digester from the XML rule set
 
 
 
        DigesterLoader  digesterLoader = DigesterLoader.newLoader(new FromXmlRulesModule() {
             
            @Override
            protected void loadRules() {
                // TODO Auto-generated method stub
                loadXMLRules( getClass( ).getResource("/com/tatu/resources/digester-catalog-rules.xml"));
 
            }
        });
Digester digester = digesterLoader.newDigester();
 
List<Catalog> catalogs = new ArrayList<Catalog>();
 
        // Push a reference to the plays List on to the Stack
 
        digester.push(catalogs);
 
 
 
        // Parse the XML document
 
        InputStream input = Digester.class.getClass().getResourceAsStream("/com/tatu/resources/chain-config.xml");
 
        try {
            Object root = digester.parse(input);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
 
    }
 
}

Готово. Итак, загрузили объект каталогов с данными XML.
Очки, которые следует отметить из приведенного выше решения:

  1. object-create-rule создает объект
  2. Остальные правила просты, как следует из их названия, object-create-rule создает новый экземпляр, set-properties-rule устанавливает свойства объекта из атрибутов xml, таких как атрибут name элемента каталога, тогда как bean-property-setter-rule set устанавливает свойства объекта из вложенных XML-элементов, таких как, например, <catalog> <name> reparam </ name> </ catalog> вместо <catalog name = ‘reparam’> </ catalog>
  3. set-next-rule: (используется для рекурсии) set-next-rulerule перемещается к следующему каталогу, цепочке и тэгам команд. Вы также указали метод для вызова в каждом случае, который будет добавлять объекты в коллекцию, определенную в родительском классе, например: <set-next-rule methodname = ‘addCommands’ paramtype = ‘Command’ />, здесь addCommands () Метод добавляет объект команды к объекту коллекции команд, определенному в классе родительской цепочки.
  4. Вы хотите новые пользовательские правила, создайте свой собственный класс Rule, производный от класса Ru в метантенка

Есть вопросы, оставляйте свои комментарии.

Еще одна мысль, вы не хотите, чтобы все эти дерьмо между файлами XML и классами Java. Угадайте что, есть хитрость, чтобы избежать этого. Но мне не нравится этот трюк, если вы не спешите. Но каждый раз, когда вы используете ярлык, вы должны потерять гибкость.

Хитрость в том, чтобы использовать Apache Betwixt. Не забудьте использовать Betwixt, вам нужно использовать Apache Digester 2.1. Для получения дополнительной перейдите на сайт Apache Betwixt.

Используйте Betwixt BeanWriter для записи Java-бинов в файл, а затем используйте BeanReader для чтения из этого файла. Получив файл, сгенерированный из BeanWriter, вы можете изменить значения и загрузить его с BeanReader. (Нужно настроить отображение между опущенными здесь)

Приятного кодирования и не забудьте поделиться!

Ссылка: Использование Apache Digester с примером. Сделайте Easy Configuration от нашего партнера JCG Биджея Део в блоге My Software Development Blog .