4

最近、EclipseでWebServicesExplorerを起動しましたが、xs:elementJAXBによって生成された名前がそれほど冗長ではないことに気づきました。シーケンスの1つは次のとおりです。

<xs:sequence>
  <xs:element minOccurs="0" name="arg0" type="xs:string" /> 
  <xs:element minOccurs="0" name="arg1" type="xs:string" /> 
  <xs:element name="arg2" type="xs:int" /> 
</xs:sequence>

このファイルから生成されます:

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class User {
    private String firstName;
    private String lastName;
    private int age;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

私はまだJAXBの専門家ではないので、これらのarg *という名前の要素をPOJOクラスのように、意味のあるものに変更できるかどうか疑問に思っていました。

4

1 に答える 1

1

使用しているWebサービスフレームワークについては言及していませんが、動作はJAX-WS仕様に似ています。たとえば、生成されたwsdlのパーツには、「arg0」、「arg1」、...の形式の名前が付いています。パーツ(およびそれらから生成されたJava)は、インターフェース定義に入力した素敵なパラメーター名を使用しますか?

公式の回答: JAX-WS仕様(具体的にはセクション3.6.1)では、この方法で生成することが義務付けられています。名前をカスタマイズするには、@ WebParam(name = "blah")アノテーションを使用してより適切な名前を指定する必要があります。(戻り値には@WebResultを使用できますが、結果はXMLを確認した場合にのみ表示されます。)

理由: Javaの謎の1つは、抽象メソッド(したがってインターフェイスメソッド)が、デバッグ情報を使用してもパラメーター名をコンパイルしないことです。したがって、サービスモデルがインターフェイスから構築されている場合、元のコードで使用されていた名前を判別する方法はありません。

サービスが(インターフェースではなく)具象クラスから構築され、クラスがデバッグ情報を使用してコンパイルされた場合、パラメーター名を取得できます。単純なフロントエンドがこれを行います。ただし、これにより潜在的な問題が発生する可能性があります。たとえば、開発から本番環境に移行するときに、デバッグ情報をオフにし(javacフラグから-gを削除)、生成されたwsdl(したがってsoapメッセージを期待する)が変更されるため、アプリケーションが突然破損する可能性があります。したがって、JAX-WS仕様の作成者は安全なルートをたどり、@WebParamアノテーションを使用してよりわかりやすい名前を指定する必要があることを義務付けました。

各フィールドにXmlElementアノテーションを追加して名前を指定することもできますが、これはJAXBが原因であると確信していますか?POJOコードを使用してschemagenを実行すると、次のようになります(名前は正しく取得されます)。

<xs:complexType name="user">
    <xs:sequence>
      <xs:element name="age" type="xs:int"/>
      <xs:element name="firstName" type="xs:string" minOccurs="0"/>
      <xs:element name="lastName" type="xs:string" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>

あなたのコメントに基づいて、POJOを次のコードに「強制」した場合でも、名前の重複について苦情がありますか?

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlAccessType;

@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement
public class User {
    @XmlElement(name = "firstName")
    private String firstName;

    @XmlElement(name = "lastName")
    private String lastName;

    @XmlElement(name = "age")
    private int age;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
于 2012-08-10T14:10:06.707 に答える