我们还是以HelloWord为例,为更简单点,我们删除了一些Handler,只留了一些基本功能。
服务端
HelloWord.java
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); }
HelloWordImpl.java
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 = "同学们"; } }
HelloWordPublisher.java
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()); } }
客户端
HelloWord.java
package hw5; 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 = "hw5.SayHello") @ResponseWrapper(localName = "sayHelloResponse", targetNamespace = "http://ts.ch03/", className = "hw5.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); }
HelloWordImplService.java
package hw5; 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; } }
SayHello.java
package hw5; 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; } }
SayHelloResponse.java
package hw5; 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; } }
ObjectFactory.java与package-info.java省略
MapDump.java
package hw5; import java.util.Map; import java.util.Set; /** * 用于解析打印hader部分 * @author fuhd */ public class MapDump { @SuppressWarnings("rawtypes") public static void dump_map(Map map) { Set keys = map.keySet(); for(Object key : keys) { System.out.println(key + " =====> " + map.get(key)); if(map.get(key) instanceof Map){ dump_map((Map)map.get(key)); } } } }
HelloWordClient.java (注意客户端中代码)
package hw5; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.ws.BindingProvider; import javax.xml.ws.Holder; import javax.xml.ws.handler.MessageContext; public class HelloWordClient { 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); //访问请求上下文对象 Map<String,Object> req_ctx = ((BindingProvider)port).getRequestContext(); req_ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://localhost:7654/ts"); req_ctx.put(BindingProvider.SOAPACTION_URI_PROPERTY, "ts"); //设置头信息 Map<String,List<String>> my_header = new HashMap<String,List<String>>(); my_header.put("TEST", Collections.singletonList("HAHA")); req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, my_header); System.out.println("~~~~~~~~~~~~~~~~~打印请求的上下文信息~~~~~~~~~~~~~~~~~~"); MapDump.dump_map(req_ctx); port.sayHello(name, wh, hf); System.out.println("~~~~~~~~~~~~~~~~打印请求响应的上下文信息~~~~~~~~~~~~~~~~"); Map<String,Object> resp_ctx = ((BindingProvider)port).getResponseContext(); MapDump.dump_map(resp_ctx); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); System.out.println(hf.value + "," + wh.value); } }
客户端打印结果:
~~~~~~~~~~~~~~~~~打印请求的上下文信息~~~~~~~~~~~~~~~~~~ javax.xml.ws.soap.http.soapaction.uri =====> ts javax.xml.ws.service.endpoint.address =====> http://localhost:7654/ts javax.xml.ws.soap.http.soapaction.use =====> null javax.xml.ws.http.request.headers =====> {TEST=[HAHA]} TEST =====> [HAHA] com.sun.xml.internal.ws.client.ContentNegotiation =====> none ~~~~~~~~~~~~~~~~打印请求响应的上下文信息~~~~~~~~~~~~~~~~ javax.xml.ws.wsdl.port =====> {http://ts.ch03/}HelloWordImplPort javax.xml.ws.soap.http.soapaction.uri =====> null com.sun.xml.internal.ws.server.OneWayOperation =====> true com.sun.xml.internal.ws.client.handle =====> JAX-WS RI 2.2.4-b01: Stub for http://localhost:7654/ts javax.xml.ws.reference.parameters =====> [] javax.xml.ws.wsdl.service =====> {http://ts.ch03/}HelloWordImplService com.sun.xml.internal.ws.api.server.WSEndpoint =====> null javax.xml.ws.http.response.code =====> 200 javax.xml.ws.wsdl.interface =====> {http://ts.ch03/}HelloWord javax.xml.ws.wsdl.operation =====> {http://ts.ch03/}sayHello com.sun.xml.internal.ws.handler.config =====> com.sun.xml.internal.ws.client.HandlerConfiguration@72dc45 javax.xml.ws.http.response.headers =====> {null=[HTTP/1.1 200 OK], Content-type=[text/xml; charset=utf-8], Date=[Sat, 17 May 2014 02:47:13 GMT], Transfer-encoding=[chunked]} null =====> [HTTP/1.1 200 OK] Content-type =====> [text/xml; charset=utf-8] Date =====> [Sat, 17 May 2014 02:47:13 GMT] Transfer-encoding =====> [chunked] javax.xml.ws.service.endpoint.address =====> http://localhost:7654/ts javax.xml.ws.soap.http.soapaction.use =====> null com.sun.xml.internal.ws.api.message.HeaderList =====> [] com.sun.xml.internal.ws.client.ContentNegotiation =====> none ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 同学们,你们好
HelloWordClient程序通过对port所引用对象获得了访问HTTP请求头信息的能力。这里首先将port引用的对象转型为BindingProvider,这样可以通过BindingProvider所提供的getRequestContext方法获得当前上下文对象的引用。getRequestContext方法返回一个Map引用。
客户端还创建了一个名为my_header的空的Map对象,该对象可接收的键/值类型为:String/Object。其中对象类型为一个由工具类Collections的singletonList方法产生的List<String>对象。通过my_header将额外的键/值对插入HTTP请求头中。尽管针对服务操作sayHello只调用一次,但是自这以后的每次调用产生的HTTP请求均包括加入的头信息。
在HelloWordClient程序的末尾处,又一次将port引用的对象实例转型为BindingProvider,然后调用getResponseContext方法获得HTTP请求响应的上下文对象,该对象同样也是一个Map类型。