WebサービスのパラメータをBeanにする

今まで作成したWebサービスのパラメータは、Stringだったが、Java Beanにすることも出来る。
まぁ、これが出来なかったら使えない。
今回、例としてname, age, Organizationを持つPersonクラスと、nameとaddressを持つ、Organizationクラスを定義する。

package sample.model;
 
import javax.xml.bind.annotation.XmlElement;
 
public class Person {
 
    private String name;
    private int age;
    private Organization work;
 
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @XmlElement(name="previousWork")
    public Organization getWork() {
        return work;
    }
    public void setWork(Organization work) {
        this.work = work;
    }
}
package sample.model;
 
import javax.xml.bind.annotation.XmlElement;
 
public class Organization {
 
    private String name;
    private String address;
 
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @XmlElement(nillable=true)
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
}


サービスとしては、Personを引数にとるattendメソッドを持つ、Meetingクラスを用意する。

package sample.webservice;
 
import javax.jws.WebMethod;
import javax.jws.WebService;
 
import sample.model.Person;
 
@WebService
public class Meeting {
 
    @WebMethod
    public String attend(Person person) {
        String message;
 
        message = person.getName() + "(" + person.getWork().getName() + ")の参加を受付けました。";
        return message;
 
    }
}


この場合でも、何の問題なくWebサービスは作成可能である。
また、Beanのgetterに@XmlElementアノテーションを設定している。
そうすることで、WSDLXMLのパラメータ名や属性を設定することが出来る。
出来たWSDLは以下の通り。

<definitions name='MeetingService' targetNamespace='http://webservice.sample/' xmlns='http://schemas.xmlsoap.org/wsdl/' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:tns='http://webservice.sample/' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
 <types>
  <xs:schema targetNamespace='http://webservice.sample/' version='1.0' xmlns:tns='http://webservice.sample/' xmlns:xs='http://www.w3.org/2001/XMLSchema'>
   <xs:element name='attend' type='tns:attend'/>
   <xs:element name='attendResponse' type='tns:attendResponse'/>
   <xs:complexType name='attend'>
    <xs:sequence>
     <xs:element minOccurs='0' name='arg0' type='tns:person'/>
    </xs:sequence>
   </xs:complexType>
   <xs:complexType name='person'>
    <xs:sequence>
     <xs:element name='age' type='xs:int'/>
     <xs:element minOccurs='0' name='name' type='xs:string'/>
     <xs:element minOccurs='0' name='previousWork' type='tns:organization'/>
    </xs:sequence>
   </xs:complexType>
   <xs:complexType name='organization'>
    <xs:sequence>
     <xs:element minOccurs='0' name='address' nillable='true' type='xs:string'/>
     <xs:element minOccurs='0' name='name' type='xs:string'/>
    </xs:sequence>
   </xs:complexType>
   <xs:complexType name='attendResponse'>
    <xs:sequence>
     <xs:element minOccurs='0' name='return' type='xs:string'/>
    </xs:sequence>
   </xs:complexType>
  </xs:schema>
 </types>
 <message name='Meeting_attend'>
  <part element='tns:attend' name='attend'></part>
 </message>
 <message name='Meeting_attendResponse'>
  <part element='tns:attendResponse' name='attendResponse'></part>
 </message>
 <portType name='Meeting'>
  <operation name='attend' parameterOrder='attend'>
   <input message='tns:Meeting_attend'></input>
   <output message='tns:Meeting_attendResponse'></output>
  </operation>
 </portType>
 <binding name='MeetingBinding' type='tns:Meeting'>
  <soap:binding style='document' transport='http://schemas.xmlsoap.org/soap/http'/>
  <operation name='attend'>
   <soap:operation soapAction=''/>
   <input>
    <soap:body use='literal'/>
   </input>
   <output>
    <soap:body use='literal'/>
   </output>
  </operation>
 </binding>
 <service name='MeetingService'>
  <port binding='tns:MeetingBinding' name='MeetingPort'>
   <soap:address location='http://localhost:8080/WebSample/services/Meeting'/>
  </port>
 </service>
</definitions>

PersonのgetWorkに「@XmlElement(name=”previousWork”)」を設定しているため、「」となっている。
また、OrganizationのgetAddressに「@XmlElement(nillable=true)」を設定しているため「」となっている。
これらのアノテーションの設定については、JAXB(Java Architecture for XML Binding)というJavaのオブジェクトからXMLシリアライズXMLからJavaのオブジェクトをデシリアライズする仕組みを使用している。
詳細は以下を参照。
http://www.jcp.org/en/jsr/detail?id=222

では、クライアント側はどうなるのかというとこちらも問題ない。
Javaソースを生成すると、Personクラス、Organizationクラスも生成されるため、問題なく開発が可能である。