我们还是以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类型。