0

继我最近关于 在 Java 中解析 XML 文件的问题之后,我决定使用 commons-digester 库。我现在熟悉这个过程,现在想创建一个表示 XML 文件的 Java 类,这样当用户实例化该类的新对象时,XML 文件中的所有数据都将可用。

为了说明这一点,我有一个名为 MyConfig.xml 的 XML 文件,其结构如下:

<MyConfig>
    <ServerName>nile</ServerName>
    <ServerPort>8079</ServerPort>
</MyConfig>

我还有一个名为 MyConfig.java 的 Java 类,它代表这个 XML 文件。它有一个构造函数,它接收 XML 文件的位置,然后解析并输出 XML 文件的内容。该类具有以下结构:

package com.digestersample;

import java.io.File;
import java.io.IOException;

import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;

public class MyConfig {
    private String serverName;
    private String serverPort;

    public MyConfig(String configFile) throws IOException, SAXException
    {
        Digester digester = new Digester();
        digester.setValidating(false);

        digester.addObjectCreate("MyConfig", MyConfig.class);

        digester.addCallMethod("MyConfig/ServerName", "setServerName", 0);
        digester.addCallMethod("MyConfig/ServerPort", "setServerPort", 0);

        System.out.println("Creating MyConfig...");
        MyConfig mc = (MyConfig) digester.parse(new File(configFile));
        System.out.println("Done.");

        System.out.println("Port: " + mc.getServerName());
        System.out.println("Port: " + mc.getServerPort());
    }

    public String getServerName() {
        return serverName;
    }

    public void setServerName(String serverName) {
        this.serverName = serverName;
    }

    public String getServerPort() {
        return serverPort;
    }

    public void setServerPort(String serverPort) {
        this.serverPort = serverPort;
    }

}

我的问题是,如何更改此类,以便每当其他组件实例化该类的新对象时,XML 文件的内容将在实例中可用。例如:

package com.digestersample;

import java.io.IOException;

import org.xml.sax.SAXException;

public class MyOtherClass {

    public static void main(String[] args) {

        MyConfig mc;
        try {

            mc = new MyConfig("/home/user/MyConfig.xml");

            System.out.println( mc.getServerName() );
            System.out.println( mc.getServerPort() );

        } catch (IOException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }

    }

}

目前,上述实例化导致 java.lang.InstantiationException。

谢谢。

4

2 回答 2

1

我意识到这不是您问题的直接答案,但是对于这样一个简单的配置以及您遇到的问题来说,这真是一大堆代码。正如您在原始帖子 Simple XML http://simple.sourceforge.net中提到的那样,我认为这项工作做得更好。

@Root
public class MyConfig {

  @Element
  private String serverName;

  @Element
  private int serverPort

  public MyConfig() {
     super();
  }

  public MyConfig(File file) {
     Style style = new CamelCaseStyle();
     Persister persister = new Persister(style);

     persister.read(this, file);
  }

  public String getServerName() {
    return name;
  }

  public int getServerPort() {
    return port;
  }
}

并创建它。

MyConfig mc = new MyConfig("/home/user/MyConfig.xml");

System.out.println("Name: " + mc.getServerName());
System.out.println("Port: " + mc.getServerPort());

完毕!你不会看到任何例外。此外,对于您的消化器异常,您缺少类似于我添加到 MyConfig 示例中的公共无参数构造函数。

于 2009-01-14T10:28:38.617 回答
0

自从我查看公共摘要器以来已经有一段时间了,但我希望InstantiationException是因为摘要器希望MyConfig类是JavaBean。JavaBean 的定义特征之一是它有一个公共的、零参数的构造函数

您可能会考虑使用其他类来创建您的MyConfig实例:

public class MyConfigFactory

    public MyConfig createMyConfig(String configFile) throws IOException, SAXException
    {
        Digester digester = new Digester();
        digester.setValidating(false);

        digester.addObjectCreate("MyConfig", MyConfig.class);

        digester.addCallMethod("MyConfig/ServerName", "setServerName", 0);
        digester.addCallMethod("MyConfig/ServerPort", "setServerPort", 0);

        MyConfig mc = (MyConfig) digester.parse(new File(configFile));

        return mc;
    }

}
于 2009-01-14T10:49:55.453 回答