64

XSD から JAXB クラスを生成すると、次のように、要素にmaxOccurs="unbounded"は getter メソッドが生成されますが、setter メソッドはありません。

/**
 * Gets the value of the element3 property.
 * 
 * <p>
 * This accessor method returns a reference to the live list,
 * not a snapshot. Therefore any modification you make to the
 * returned list will be present inside the JAXB object.
 * This is why there is not a <CODE>set</CODE> method for the element3 property.
 * 
 * <p>
 * For example, to add a new item, do as follows:
 * <pre>
 *    getElement3().add(newItem);
 * </pre>
 * 
 * 
 * <p>
 * Objects of the following type(s) are allowed in the list
 * {@link Type }
 * 
 * 
 */
public List<Type> getElement3() {
    if (element3 == null) {
        element3 = new ArrayList<Type>();
    }
    return this.element3;
}

メソッドのコメントは、それをどのように使用できるかを非常に明確にしていますが、私の質問は次
のとおりです。Java Beans ルールに従って、なぜ JAXB は単にセッターを生成しないのですか? セッター メソッドを自分で記述できることはわかっていますが、生成されたゲッター メソッドで提案されているアプローチに利点はありますか?

これは私のXSDです:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.example.org/DoTransfer/" targetNamespace="http://www.example.org/DoTransfer/">

    <element name="CollectionTest" type="tns:CollectionTest"></element>

    <complexType name="CollectionTest">
        <sequence>
            <element name="element1" type="string" maxOccurs="1" minOccurs="1"></element>
            <element name="element2" type="boolean" maxOccurs="1" minOccurs="1"></element>
            <element name="element3" type="tns:type" maxOccurs="unbounded" minOccurs="1" nillable="true"></element>
        </sequence>
    </complexType>


    <complexType name="type">
        <sequence>
            <element name="subelement1" type="string" maxOccurs="1" minOccurs="1"></element>
            <element name="subelement2" type="string" maxOccurs="1" minOccurs="0"></element>
        </sequence>
    </complexType>
</schema>
4

6 に答える 6

33

JAXB 仕様 - ページ 60 からの正当化は次のとおりです。

設計上の注意 – List プロパティのセッター メソッドはありません。ゲッターは参照によってリストを返します。java.util.List で定義された適切なメソッドを使用して、getter メソッドによって返される List にアイテムを追加できます。JAXB 1.0 でのこの設計の理論的根拠は、実装がリストをラッパーし、リストにコンテンツが追加または削除されたときにチェックを実行できるようにすることでした。

したがって、リストの実装が検証を実行するために追加/削除をオーバーライドしていた場合、その「特別な」リストを (たとえば) ArrayList に置き換えると、これらのチェックが無効になります。

于 2014-08-26T13:34:10.893 に答える
31

リンク先:リストのセッターなし

getterメソッドのコードは、リストが作成されることを保証します。対応するセッターはありません。つまり、リスト要素のすべての追加または削除は「ライブ」 リストで行う必要があります。

getterメソッドを使用する場合のように、引用符にはセッターがないことが示されているため、リストの新しいインスタンスが存在しない場合は確実に初期化されます。

その後、何かを追加または削除する必要がある場合は、使用する必要があります

getElement3().add(Type);

更新:マーシャリングnullと空のリストの違い

リストがnull

@XmlRootElement(name = "list-demo")
public class ListDemo {

    @XmlElementWrapper(name = "list")
    @XmlElement(name = "list-item")
    private List<String> list;

}

出力は

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<list-demo/>

リストが空の例

@XmlRootElement(name = "list-demo")
public class ListDemo {

    @XmlElementWrapper(name = "list")
    @XmlElement(name = "list-item")
    private List<String> list = new ArrayList<String>();

}

出力は次のようになります。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<list-demo>
    <list/>
</list-demo>
于 2012-12-17T12:21:41.347 に答える
1

プラグイン内に依存関係を追加する必要があります。たとえば、以下のように、

<plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>jaxb2-maven-plugin</artifactId>
                    <version>1.5</version>
                    <dependencies>
                    <dependency>
                        <groupId>org.andromda.thirdparty.jaxb2_commons</groupId>
                        <artifactId>collection-setter-injector</artifactId>
                        <version>1.0</version>
                    </dependency>
                    </dependencies>
                    <configuration>
                        <schemaDirectory>${project.basedir}/epc</schemaDirectory>
                        <arguments>-Xcollection-setter-injector</arguments>
                        <clearOutputDir>false</clearOutputDir>
                        <extension>true</extension>
                    </configuration>
                    <executions>
                        <execution>
                            <id>generate-java-from-xsd-1</id>
                            <phase>generate-sources</phase>
                            <goals>
                                <goal>xjc</goal>
                            </goals>
                            <configuration>
                                <packageName>${package name}</packageName>
                                <schemaFiles>example.xsd</schemaFiles>
                                <schemaDirectory>${project.basedir}/epc</schemaDirectory>
                                <bindingFiles>example_1.xjb</bindingFiles>
                                <bindingDirectory>${project.basedir}/generate</bindingDirectory>
                                <staleFile>${project.build.directory}/jaxb2/.xjc1StaleFlag</staleFile>
                            </configuration>
                        </execution>
              </plugin>

于 2020-06-30T12:20:42.117 に答える