文档章节

创建异步的客户端

柳哥
 柳哥
发布于 2014/04/10 15:23
字数 1371
阅读 178
收藏 3

前面博客中,我们通过WSDL创建的客户端几乎都是同步的,也就是从web服务端有响应返回或有一个异常抛出之前,调用将一直阻塞。另外JWS也支持客户端对web服务的非阻塞或异步方式调用(注:好像RPC样式的不支持异步调用)。

以前面的HelloWord为例,我们调用下面的命令:

% wsimport -s source -p hw3 http://localhost:7654/ts?wsdl -b custom.xml

为了创建非阻塞的客户端(或者异步的客户端),这里我们使用了定制化的绑定文件:custom.xml。custom.xml中的内容如下:

<jaxws:bindings wsdlLocation = "http://localhost:7654/ts?wsdl" 
        xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
    <jaxws:enableAsyncMapping>true</jaxws:enableAsyncMapping>
</jaxws:bindings>

文档中将enableAsyncMapping属性值设置为true。这样生成的客户端代码如下:

HelloWord.java:

package hw3;

import java.util.concurrent.Future;
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.AsyncHandler;
import javax.xml.ws.Holder;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.Response;
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
     * @return
     * returns javax.xml.ws.Response<hw3.SayHelloResponse>
     */
    @WebMethod(operationName = "sayHello")
    @RequestWrapper(localName = "sayHello", targetNamespace = "http://ts.ch03/", 
        className = "hw3.SayHello")
    @ResponseWrapper(localName = "sayHelloResponse", targetNamespace = "http://ts.ch03/", 
        className = "hw3.SayHelloResponse")
    public Response<SayHelloResponse> sayHelloAsync(
        @WebParam(name = "name", targetNamespace = "")
        String name,
        @WebParam(name = "wh", targetNamespace = "")
        String wh);
        
    /**
     * @param wh
     * @param name
     * @param asyncHandler
     * @return
     * returns java.util.concurrent.Future<? extends java.lang.Object>
     */
    @WebMethod(operationName = "sayHello")
    @RequestWrapper(localName = "sayHello", targetNamespace = "http://ts.ch03/", 
        className = "hw3.SayHello")
    @ResponseWrapper(localName = "sayHelloResponse", targetNamespace = "http://ts.ch03/", 
        className = "hw3.SayHelloResponse")
    public Future<?> sayHelloAsync(
        @WebParam(name = "name", targetNamespace = "")
        String name,
        @WebParam(name = "wh", targetNamespace = "")
        String wh,
        @WebParam(name = "asyncHandler", targetNamespace = "")
        AsyncHandler<SayHelloResponse> asyncHandler);

    /**
     * @param wh
     * @param name
     * @param hf
     */
    @WebMethod
    @RequestWrapper(localName = "sayHello", targetNamespace = "http://ts.ch03/", 
        className = "hw3.SayHello")
    @ResponseWrapper(localName = "sayHelloResponse", targetNamespace = "http://ts.ch03/", 
        className = "hw3.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 hw3;

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 hw3;

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>
 * &lt;complexType name="sayHello">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="name" type="{http://www.w3.org/2001/XMLSchema}string"
 *                minOccurs="0"/>
 *         &lt;element name="wh" type="{http://www.w3.org/2001/XMLSchema}string"
 *                minOccurs="0"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/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 hw3;

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>
 * &lt;complexType name="sayHelloResponse">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="wh" type="{http://www.w3.org/2001/XMLSchema}string" 
 *                minOccurs="0"/>
 *         &lt;element name="hf" type="{http://www.w3.org/2001/XMLSchema}string" 
 *                minOccurs="0"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/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略。

异步调用可以采用不同方式。第一种方式的客户端异步调用示例如下:

package hw3;

import java.util.concurrent.ExecutionException;
import hw3.HelloWord;
import hw3.HelloWordImplService;
import javax.xml.ws.Response;

public class HelloWordClient3 {
	public static void main(String[] args) {
		String name = "老师";
		String wh = "你好";
		HelloWordImplService service = new HelloWordImplService();
		HelloWord port = service.getPort(HelloWord.class);
		Response<SayHelloResponse> resp = port.sayHelloAsync(name, wh);
		//响应是否完成
		while(!resp.isDone()){
			System.out.println("is not Done!");
		}
		try {
			SayHelloResponse response = resp.get();
			String hf1 = response.getHf();
			String wh1 = response.getWh();
			System.out.println(hf1 + "!" + wh1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}
}

这个示例是以轮询的方式(polling)实现异步调用。

第二个异步调用方式示例如下:

package hw3;

import java.util.concurrent.ExecutionException;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;

public class HelloWordClient3 {
	public static void main(String[] args) {
		String name = "老师";
		String wh = "你好";
		HelloWordImplService service = new HelloWordImplService();
		HelloWord port = service.getPort(HelloWord.class);
		//这里使用了一个匿名内部类
		port.sayHelloAsync(name, wh, new AsyncHandler<SayHelloResponse>(){
			public void handleResponse(Response<SayHelloResponse> future){
				try {
					SayHelloResponse response = future.get();
					String hf1 = response.getHf();
					String wh1 = response.getWh();
					System.out.println(hf1 + "!" + wh1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (ExecutionException e) {
					e.printStackTrace();
				}
			}
		});
		System.out.println("测试一下在之前还是在之后打印!!!");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

这个示例是以回调的方式(callback)来演示异步调用的。由于此callback当请求发出去以后,当前的这个连接就会关闭,为了达到测试目的,加入 sleep,让客户端程序等待服务端的返回。注意,这个方法要传入一个javax.xml.ws.AsyncHandler类型的对象,所以这里我们定义了一个匿名内部类。当SOAP响应消息到达时,JAXWS会调用handleResponse这个方法来处理response。


© 著作权归作者所有

柳哥
粉丝 207
博文 405
码字总数 347782
作品 0
杭州
技术主管
私信 提问
花花世界欢乐多/swoole-worker

swoole-worker 关于本项目 此项目是workerman(v3.4.5)的swoole移植版本,移除了对pcntl,libevent,event,ev扩展的依赖,转而使用swoole提供的swooleprocess和swooleevent,定时器采用swoole的s...

花花世界欢乐多
2017/08/15
0
0
使用 acl 库编写高并发非阻塞网络通信程序

一、概述 acl 库的 C 库(libacl) 的 aio 模块设计了完整的非阻塞异步 IO 通信过程,在 acl 的C++库(libaclcpp) 中封装并增强了异步通信的功能,本文主要描述了 acl C++ 库之非阻塞IO库的设计...

郑树新
2014/08/25
1K
0
异步RPC框架--Missian

大家都知道,Hessian是一个了不起的RPC框架。但是,它的调用是同步的,并且只能基于HTTP传输。 作者创建missian(mina+hessian的意思)的目的有二: 1、实现异步的RPC调用。同步远程操作带来...

匿名
2010/11/29
10.7K
1
基于TCP/IP协议的聊天实例

版权声明:欢迎转载,转载请注明出处 https://blog.csdn.net/weixin_38239050/article/details/86562267 一、认识Socket Skcket:套接字 Socket怎样传输数据? 客户端: 1、链接:connect,连...

橙子va
01/20
0
0
请问servlet端异步处理有什么好处?

服务端的同步模式:客户端请求 -> servlet容器创建线程 -> 线程中IO(可能是长时间的) -> 响应客户端 服务端异步模式:客户端请求 -> servlet容器创建线程A -> 将长IO操作封装到新线程B中 ->...

osc4alex
2014/11/04
423
2

没有更多内容

加载失败,请刷新页面

加载更多

PyTorch入门笔记一

张量 引入pytorch,生成一个随机的5x3张量 >>> from __future__ import print_function>>> import torch>>> x = torch.rand(5, 3)>>> print(x)tensor([[0.5555, 0.7301, 0.5655],......

仪山湖
15分钟前
1
0
OSChina 周二乱弹 —— 开发语言和语言开发的能一样么

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @花间小酌:#今日歌曲推荐# 分享The Score的单曲《Revolution》 《Revolution》- The Score 手机党少年们想听歌,请使劲儿戳(这里) @批判派...

小小编辑
今天
1K
17
oracle ORA-39700: database must be opened with UPGRADE option

ORA-01092: ORACLE instance terminated. Disconnection forced ORA-00704: bootstrap process failure ORA-39700: database must be opened with UPGRADE option 进程 ID: 3650 会话 ID: 29......

Tank_shu
今天
3
0
分布式协调服务zookeeper

ps.本文为《从Paxos到Zookeeper 分布式一致性原理与实践》笔记之一 ZooKeeper ZooKeeper曾是Apache Hadoop的一个子项目,是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它...

ls_cherish
今天
4
0
聊聊DubboDefaultPropertiesEnvironmentPostProcessor

序 本文主要研究一下DubboDefaultPropertiesEnvironmentPostProcessor DubboDefaultPropertiesEnvironmentPostProcessor dubbo-spring-boot-project-2.7.3/dubbo-spring-boot-compatible/au......

go4it
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部