0

Java での XML ファイルの解析に関する最近の質問を受けて 、commons-digester ライブラリを使用することにしました。このプロセスに慣れてきたので、XML ファイルを表す Java クラスを作成して、ユーザーがそのクラスの新しいオブジェクトをインスタンス化したときに、XML ファイルのすべてのデータを使用できるようにしたいと考えています。

これを説明するために、次の構造を持つ MyConfig.xml という XML ファイルがあります。

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

この XML ファイルを表す MyConfig.java という Java クラスもあります。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 の例に追加したものと同様の public no argument コンストラクターがありません。

于 2009-01-14T10:28:38.617 に答える
0

コモンズダイジェスターを調べてからしばらく経ちましたが、InstantiationExceptionは、ダイジェスターがMyConfigクラスをJavaBeanであると想定しているためだと思います。JavaBeanの特徴の1つは、パブリックのゼロ引数コンストラクターを備えていることです。

他のクラスを使用して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 に答える