这一次,我们写一个非常简单的示例来演示。
服务端接口定义:
package ch03.ts; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import javax.xml.ws.Holder; @WebService public interface HelloWord { @WebMethod void sayHello(@WebParam(name="name") String name, @WebParam(name="wh",mode=WebParam.Mode.INOUT) Holder<String> wh, @WebParam(name="hf",mode=WebParam.Mode.OUT) Holder<String> hf); }
参数的@WebParam注解中,没有定义mode,表示默认为WebParam.Mode.IN,代表输入参数。如果mode为WebParam.Mode.INOUT,代表既是输入参数也是输出参数。如果mode为WebParam.Mode.OUT,代表是输出参数。
另外 ,我们再研究一下Holder类型:javax.xml.ws.Holder。Holder类型专门用于mode为INOUT和OUT的情况。在java中,传参是按值传递的,也就是mode为IN的正常情况,而INOUT与OUT是要按引用传递的,所以我们需要使用Holder类型来变通实现它。Holder对象的引用指向堆空间中的一个Holder实例,该引用的副本作为参数传递给方法,那么该引用与副本引用同时指向堆空间中的Holder对象,然后该Holder对象中的值,也就是真实使用的对象的引用。这样就变向实现了引用传递,真实对象的引用与传参后真实对象的引用是同一个引用,不是副本。(这是看网络文章的总结,不一定正确!!将就着看吧!!!呵呵)
服务实现:
package ch03.ts; import javax.jws.WebService; import javax.xml.ws.Holder; @WebService(endpointInterface = "ch03.ts.HelloWord") public class HelloWordImpl implements HelloWord { @Override public void sayHello(String name, Holder<String> wh, Holder<String> hf) { System.out.println(name + "!" + wh.value); wh.value = "你们好"; hf.value = "同学们"; } }
服务发布:
package ch03.ts; import javax.xml.ws.Endpoint; public class HelloWordPublisher { public static void main(String[] args) { Endpoint.publish("http://localhost:7654/ts", new HelloWordImpl()); } }
通过如下代码生成包装的document样式客户端:
% wsimport -keep -p hw1 http://localhost:7654/ts?wsdl
客户端代码如下:
package hw1; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.ws.Action; import javax.xml.ws.Holder; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper; /** * This class was generated by the JAX-WS RI. * JAX-WS RI 2.2.4-b01 * Generated source version: 2.2 */ @WebService(name = "HelloWord", targetNamespace = "http://ts.ch03/") @XmlSeeAlso({ ObjectFactory.class }) public interface HelloWord { /** * @param wh * @param name * @param hf */ @WebMethod @RequestWrapper(localName = "sayHello", targetNamespace = "http://ts.ch03/", className = "hw1.SayHello") @ResponseWrapper(localName = "sayHelloResponse", targetNamespace = "http://ts.ch03/", className = "hw1.SayHelloResponse") @Action(input = "http://ts.ch03/HelloWord/sayHelloRequest", output = "http://ts.ch03/HelloWord/sayHelloResponse") public void sayHello( @WebParam(name = "name", targetNamespace = "") String name, @WebParam(name = "wh", targetNamespace = "", mode = WebParam.Mode.INOUT) Holder<String> wh, @WebParam(name = "hf", targetNamespace = "", mode = WebParam.Mode.OUT) Holder<String> hf); }
package hw1; import java.net.MalformedURLException; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; import javax.xml.ws.WebEndpoint; import javax.xml.ws.WebServiceClient; import javax.xml.ws.WebServiceException; import javax.xml.ws.WebServiceFeature; /** * This class was generated by the JAX-WS RI. * JAX-WS RI 2.2.4-b01 * Generated source version: 2.2 */ @WebServiceClient(name = "HelloWordImplService", targetNamespace = "http://ts.ch03/", wsdlLocation = "http://localhost:7654/ts?wsdl") public class HelloWordImplService extends Service { private final static URL HELLOWORDIMPLSERVICE_WSDL_LOCATION; private final static WebServiceException HELLOWORDIMPLSERVICE_EXCEPTION; private final static QName HELLOWORDIMPLSERVICE_QNAME = new QName("http://ts.ch03/", "HelloWordImplService"); static { URL url = null; WebServiceException e = null; try { url = new URL("http://localhost:7654/ts?wsdl"); } catch (MalformedURLException ex) { e = new WebServiceException(ex); } HELLOWORDIMPLSERVICE_WSDL_LOCATION = url; HELLOWORDIMPLSERVICE_EXCEPTION = e; } public HelloWordImplService() { super(__getWsdlLocation(), HELLOWORDIMPLSERVICE_QNAME); } public HelloWordImplService(WebServiceFeature... features) { super(__getWsdlLocation(), HELLOWORDIMPLSERVICE_QNAME, features); } public HelloWordImplService(URL wsdlLocation) { super(wsdlLocation, HELLOWORDIMPLSERVICE_QNAME); } public HelloWordImplService(URL wsdlLocation, WebServiceFeature... features) { super(wsdlLocation, HELLOWORDIMPLSERVICE_QNAME, features); } public HelloWordImplService(URL wsdlLocation, QName serviceName) { super(wsdlLocation, serviceName); } public HelloWordImplService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) { super(wsdlLocation, serviceName, features); } /** * @return * returns HelloWord */ @WebEndpoint(name = "HelloWordImplPort") public HelloWord getHelloWordImplPort() { return super.getPort(new QName("http://ts.ch03/", "HelloWordImplPort"), HelloWord.class); } /** * @param features * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. * Supported features not in the <code>features</code> parameter will * have their default values. * @return * returns HelloWord */ @WebEndpoint(name = "HelloWordImplPort") public HelloWord getHelloWordImplPort(WebServiceFeature... features) { return super.getPort(new QName("http://ts.ch03/", "HelloWordImplPort"), HelloWord.class, features); } private static URL __getWsdlLocation() { if (HELLOWORDIMPLSERVICE_EXCEPTION!= null) { throw HELLOWORDIMPLSERVICE_EXCEPTION; } return HELLOWORDIMPLSERVICE_WSDL_LOCATION; } }
package hw1; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlType; /** * <p>Java class for sayHello complex type. * <p>The following schema fragment specifies the expected content contained within this class. * <pre> * <complexType name="sayHello"> * <complexContent> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <sequence> * <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/> * <element name="wh" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/> * </sequence> * </restriction> * </complexContent> * </complexType> * </pre> */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "sayHello", propOrder = { "name", "wh" }) public class SayHello { protected String name; protected String wh; /** * Gets the value of the name property. * @return * possible object is * {@link String } */ public String getName() { return name; } /** * Sets the value of the name property. * @param value * allowed object is * {@link String } */ public void setName(String value) { this.name = value; } /** * Gets the value of the wh property. * @return * possible object is * {@link String } */ public String getWh() { return wh; } /** * Sets the value of the wh property. * @param value * allowed object is * @link String } */ public void setWh(String value) { this.wh = value; } }
package hw1; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlType; /** * <p>Java class for sayHelloResponse complex type. * <p>The following schema fragment specifies the expected content contained within this class. * <pre> * <complexType name="sayHelloResponse"> * <complexContent> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <sequence> * <element name="wh" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/> * <element name="hf" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/> * </sequence> * </restriction> * </complexContent> * </complexType> * </pre> */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "sayHelloResponse", propOrder = { "wh", "hf" }) public class SayHelloResponse { protected String wh; protected String hf; /** * Gets the value of the wh property. * @return * possible object is * {@link String } */ public String getWh() { return wh; } /** * Sets the value of the wh property. * @param value * allowed object is * {@link String } */ public void setWh(String value) { this.wh = value; } /** * Gets the value of the hf property. * @return * possible object is * {@link String } */ public String getHf() { return hf; } /** * Sets the value of the hf property. * @param value * allowed object is * {@link String } */ public void setHf(String value) { this.hf = value; } }
package hw1; import javax.xml.bind.JAXBElement; import javax.xml.bind.annotation.XmlElementDecl; import javax.xml.bind.annotation.XmlRegistry; import javax.xml.namespace.QName; /** * This object contains factory methods for each * Java content interface and Java element interface * generated in the hw1 package. * <p>An ObjectFactory allows you to programatically * construct new instances of the Java representation * for XML content. The Java representation of XML * content can consist of schema derived interfaces * and classes representing the binding of schema * type definitions, element declarations and model * groups. Factory methods for each of these are * provided in this class. * */ @XmlRegistry public class ObjectFactory { private final static QName _SayHello_QNAME = new QName("http://ts.ch03/", "sayHello"); private final static QName _SayHelloResponse_QNAME = new QName("http://ts.ch03/", "sayHelloResponse"); /** * Create a new ObjectFactory that can be used to create new instances of * schema derived classes for package: hw1 */ public ObjectFactory() {} /** * Create an instance of {@link SayHelloResponse } */ public SayHelloResponse createSayHelloResponse() { return new SayHelloResponse(); } /** * Create an instance of {@link SayHello } */ public SayHello createSayHello() { return new SayHello(); } /** * Create an instance of {@link JAXBElement }{@code <}{@link SayHello }{@code >}} */ @XmlElementDecl(namespace = "http://ts.ch03/", name = "sayHello") public JAXBElement<SayHello> createSayHello(SayHello value) { return new JAXBElement<SayHello>(_SayHello_QNAME, SayHello.class, null, value); } /** * Create an instance of {@link JAXBElement }{@code <} * {@link SayHelloResponse }{@code >}} */ @XmlElementDecl(namespace = "http://ts.ch03/", name = "sayHelloResponse") public JAXBElement<SayHelloResponse> createSayHelloResponse(SayHelloResponse value) { return new JAXBElement<SayHelloResponse>(_SayHelloResponse_QNAME, SayHelloResponse.class, null, value); } }
package-info.java:
@javax.xml.bind.annotation.XmlSchema(namespace = "http://ts.ch03/") package hw1;
客户端调用代码:
package hw1; import javax.xml.ws.Holder; public class HelloWordClient1 { public static void main(String[] args) { String name = "老师"; Holder<String> wh = new Holder<String>(); wh.value = "你好"; Holder<String> hf = new Holder<String>(); HelloWordImplService service = new HelloWordImplService(); HelloWord port = service.getPort(HelloWord.class); port.sayHello(name, wh, hf); System.out.println(hf.value + "," + wh.value); } }
请注意HelloWordClient1.java与HelloWord.java代码,看看与下一篇同一个示例的非包装的document样式客户端代码有什么不同。