我开始用JAX WS研究java web服务。我正在阅读的这本书的第一章展示了如何仅使用java SE构建和部署一个简单的JAX-WS web服务。特别是,web服务是通过Endpoint类发布的。发布web服务后,作者指定"开箱即用,Endpoint发布者在时间如果对给定请求的处理应该挂起,那么所有其他客户端请求都被有效地阻止。最后的一个例子本章的显示了Endpoint如何同时处理请求从而一个挂起的请求不会阻塞其他请求。"
为了看到这一点,我尝试向具有2个线程的web服务发送两个请求。这是代码:
@WebService(endpointInterface = "ProveVelociJava.WS.MyWsWithJavaSE.SayHello")
public class SayHelloImpl implements SayHello {
public String greetings(String param) {
System.out.println("nStarting " + param + "...n");
if(param.equals("miao")) {
try {
Thread.sleep(9000);
}
catch(Exception e) {}
}
System.out.println("Ended " + param + "nn");
return "Hi, " + param;
}
}
public class SayHelloPublisher {
public static void main(String[ ] args) {
// 1st argument is the publication URL
// 2nd argument is an SIB instance
Endpoint.publish("http://127.0.0.1:9899/say", new SayHelloImpl());
}
}
class MyClient extends Thread {
private static URL url;
private static QName qname;
private static Service service;
private static SayHello eif;
static {
try {
url = new URL("http://127.0.0.1:9899/say?wsdl");
qname = new QName("http://MyWsWithJavaSE.WS.ProveVelociJava/", "SayHelloImplService");
service = Service.create(MyClient.url, MyClient.qname);
// Extract the endpoint interface, the service "port".
eif = service.getPort(SayHello.class);
}
catch(Exception e) {}
}
private String name;
public MyClient(String n) {
name = n;
}
public void run() {
System.out.println(MyClient.eif.greetings(this.name));
}
public static void main(String args[ ]) throws Exception {
MyClient t1 = new MyClient("miao");
MyClient t2 = new MyClient("bau");
t1.start();
t2.start();
}
}
如果我启动MyClient类,名为"miao"的线程会发送请求,然后进入睡眠状态。但是,名为"bau"的线程不会等待前一个线程,它的请求会立即得到满足。
我是不是错过了什么?java线程可以用来模拟多个请求吗?
非常感谢你的帮助,尼科。
我下载了JAX-WS 2.0规范,它反驳了我正在读的书中所说的:
"端点由充当Web服务的对象组成实现(这里称为implementator)加上一些配置信息端点通常会被调用来提供服务并发请求,因此应该编写其实现程序以便支持多个线程。同步关键字可以用作通常用于控制对代码关键部分的访问。更精细对用于调度传入请求的线程的控制应用程序可以直接设置要使用的执行程序"
(http://jcp.org/aboutJava/communityprocess/final/jsr224/index.html,第5.2.2节"出版",第67页)
这本书谈到了JAX-WS2.1,但我没能下载那个版本的规范。无论如何,JAX-WS2.2规范(当前版本)确认了Endpoint类的并发性(它包含与上面相同的语句)。
我不知道这本书的作者到底是什么意思。
System.out.println(Thread.currentThread().toString());
若你们一个接一个地请求,这将打印相同的线程信息,因为终止的线程将在下一个http请求中重复使用。但是,如果您同时发出多个请求,那么您将看到不同的线程将调用您的Web方法。
只要你的web方法没有同步的块,整个web方法没有被同步,或者你使用了某种信号量,一个请求就不会阻止任何其他并发的请求。
虽然晚了,但可能会有所帮助。
Endpoint.publish(Url,ServiceImplObj)在给定的Url上发布Web服务。分配给请求处理的线程数量实际上由jvm控制,因为这是一个由jvm自己处理的轻量级部署。
为了更好地说明,您可以在服务端打印当前线程名称,并且可以看到服务线程是从jvm管理的线程池中分配的。
[pool-1-thread-1]: Response[57]:
[pool-1-thread-5]: Response[58]:
[pool-1-thread-4]: Response[59]:
[pool-1-thread-3]: Response[60]:
[pool-1-thread-6]: Response[61]:
[pool-1-thread-6]: Response[62]: