29

私はJAXBを学び始めているので、私の質問は非常にばかげている可能性があります。これでクラスができて、XMLスキーマを生成したいと思います。この指示に従うと例外が発生します

IllegalAnnotationExceptions...には引数なしのデフォルトコンストラクターがありません。

うん。私のクラスには、デフォルトの引数なしコンストラクターがありません。簡単すぎます。パッケージに表示されるコンストラクター/finalメソッドを備えたクラスがあり、もちろん引数を備えたクラスがあります。どうすればよいですか?特定のmomemto / builderクラスを作成するか、コンストラクターをJAXBに指定しますか(どのように?)?ありがとう。

4

4 に答える 4

42

JAXBは、XMLアダプターを使用してこのケースをサポートできます。ゼロ引数コンストラクターのない次のオブジェクトがあるとします。

package blog.immutable;

public class Customer {

    private final String name;
    private final Address address;

    public Customer(String name, Address address) {
        this.name = name;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public Address getAddress() {
        return address;
    }

}

このクラスのマッピング可能なバージョンを作成する必要があります。

package blog.immutable.adpater;

import javax.xml.bind.annotation.XmlAttribute;
import blog.immutable.Address;

public class AdaptedCustomer {

    private String name;
    private Address address;

    @XmlAttribute
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

}

そして、それらの間で変換するためのXMLアダプター:

package blog.immutable.adpater;

import javax.xml.bind.annotation.adapters.XmlAdapter;
import blog.immutable.Customer;

public class CustomerAdapter extends XmlAdapter<AdaptedCustomer, Customer> {

    @Override
    public Customer unmarshal(AdaptedCustomer adaptedCustomer) throws Exception {
        return new Customer(adaptedCustomer.getName(), adaptedCustomer.getAddress());
    }

    @Override
    public AdaptedCustomer marshal(Customer customer) throws Exception {
        AdaptedCustomer adaptedCustomer = new AdaptedCustomer();
        adaptedCustomer.setName(customer.getName());
        adaptedCustomer.setAddress(customer.getAddress());
        return adaptedCustomer;
    }

}

次に、Customerクラスを参照するプロパティについては、@XmlJavaTypeAdapterアノテーションを使用するだけです。

package blog.immutable;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import blog.immutable.adpater.CustomerAdapter;

@XmlRootElement(name="purchase-order")
public class PurchaseOrder {

    private Customer customer;

    @XmlJavaTypeAdapter(CustomerAdapter.class)
    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

} 

より詳細な例については、以下を参照してください。

于 2010-12-08T12:42:18.380 に答える
15

アノテーション@XmlTypeを使用して、factoryMethod/factoryClass属性を次のようなさまざまな組み合わせで使用できます。

@XmlType(factoryMethod="newInstance")
@XmlRootElement
public class PurchaseOrder {
    @XmlElement
    private final String address;
    @XmlElement
    private final Customer customer;

    public PurchaseOrder(String address, Customer customer){
        this.address = address;
        this.customer = customer;
    }

    private PurchaseOrder(){
        this.address = null;
        this.customer = null;
    }
    /** Creates a new instance, will only be used by Jaxb. */
    private static PurchaseOrder newInstance() {
        return new PurchaseOrder();
    }

    public String getAddress() {
        return address;
    }

    public Customer getCustomer() {
        return customer;
    }
}

驚いたことに、これは機能し、アンマーシャリング時に初期化されたインスタンスを取得します。newInstance無効なインスタンスが返されるため、コードのどこでもメソッドを呼び出さないように注意する必要があります。

于 2011-07-14T22:43:00.737 に答える
5

クラスをインスタンス化できるようにするには、JAXBのデフォルトのコンストラクターが必要です。たぶん、私にはわからない回避策があります。

JAXBは、特にBeanのようなクラスに適合しており、オブジェクトのセッターを呼び出すことでオブジェクトを構成できます。

于 2010-12-08T12:26:48.130 に答える
3

JAXBは、単純な方法でXMLからBeanを再作成します。つまり、Beanの新しいインスタンスを作成しsetXXX、属性を設定するために必要なすべてのことを実行します。したがって、Beanに引数なしのコンストラクターがない場合、JAXBはそれを作成できません。他の回答で述べたように、JAXBは、引数なしのコンストラクターが実際には問題にならない単純な「コンテナー」Beanに対してより適切に機能します。特定の初期化が必要なBeanを作成しようとしている場合は、setXXXメソッドでそれを行う必要があります。

于 2010-12-08T12:30:57.007 に答える