在此简短说明中,我想重新回顾一下我们在上一步中编写的 Web 服务客户端代码。在本例中,我假设您已打开 IDEA,并且其中包含步骤 1 中的项目。我们的 Web 服务应在该项目中启动:
package ru.javarush.client;
// нужно, чтобы получить wsdl описание и через него
// дотянуться до самого веб-сервиса
import java.net.URL;
// такой эксепшн возникнет при работе с an objectом URL
import java.net.MalformedURLException;
// классы, чтобы пропарсить xml-ку c wsdl описанием
// и дотянуться до тега service в нем
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
// интерфейс нашего веб-сервиса (нам больше и нужно)
import ru.javarush.ws.HelloWebService;
public class HelloWebServiceClient {
public static void main(String[] args) throws MalformedURLException {
// создаем ссылку на wsdl описание
URL url = new URL("http://localhost:1986/wss/hello?wsdl");
// Параметры следующего конструктора смотрим в самом первом теге WSDL описания - definitions
// 1-ый аргумент смотрим в атрибуте targetNamespace
// 2-ой аргумент смотрим в атрибуте name
QName qname = new QName("http://ws.javarush.ru/", "HelloWebServiceImplService");
// Теперь мы можем дотянуться до тега service в wsdl описании,
Service service = Service.create(url, qname);
// а далее и до вложенного в него тега port, чтобы
// получить ссылку на удаленный от нас an object веб-сервиса
HelloWebService hello = service.getPort(HelloWebService.class);
// Ура! Теперь можно вызывать удаленный метод
System.out.println(hello.getHelloString("JavaRush"));
}
}
请注意我们需要提前了解多少信息。除了您需要访问wsdl描述之外(没有这个,抱歉,没有办法):
URL url = new URL("http://localhost:1986/wss/hello?wsdl");
您需要自己打开这个 xml 文件并查看标签definitions
和其中的属性targetNamespace
并name
调用构造函数QName
:
QName qname = new QName("http://ws.javarush.ru/", "HelloWebServiceImplService");
那么你需要手动连接到标签service
:
Service service = Service.create(url, qname);
并在其中添加标签port
:
HelloWebService hello = service.getPort(HelloWebService.class);
然后我们才能调用远程方法:
hello.getHelloString("JavaRush")
问题是:这就是我们的曾祖父战死沙场的原因,所以我们现在只能靠手工完成这一切吗?如果它甚至不是我们的网络服务,而是其他人的。那么这个过程就会更加不愉快。XML 格式旨在由机器而非人类读取。所以让机器来做脏活,享受这个过程吧。为此,我们不需要做任何特别的事情,因为...... 我们最喜欢的 SDK(在 Java 中称为 JDK)包含一个名为wsimport的特殊实用程序。首先,我们要在 IDEA 中创建一个新项目,方法是从菜单中选择File > New Project...并将项目命名为HelloWS。当我们被问到在哪里打开新创建的项目时,我们需要回答New Window,即 在新窗口中,因为我会再次指出,打开上一个项目非常重要,因为 我们记得在第 1 步中,我们的 Web 服务在该项目中运行。当然,您可以简单地通过 Windows 控制台启动它,但我不喜欢这样做。在新项目中,通过选择View > Tool Windows > Terminal打开控制台,或者只需按Alt+F12。现在我们位于项目的根目录中,我们需要进入src文件夹,因此我们在控制台中输入以下命令:cd src
现在是时候使用wsimport实用程序了。它的工作原理如下:我们向它传递一个 WSDL描述,作为响应,它创建存根文件(所谓的Stub
类),其中已经包含我们访问 Web 服务所需的所有功能。这些类将被放置在包中ru.javarush.ws
。如果你问包名从何而来,答案是:包名是WSDL描述的反向目标命名空间。记住WSDLtargetNamespace
标记中definitions
的属性。在那里我们写了以下内容。这不是站点地址,这是在 xml 中描述命名空间的习惯方式,如果我们丢弃并以相反的顺序扩展剩余的内容,我们将得到包名称。因此,让我们运行该实用程序:为了使其工作,必须在PATH环境变量 中指定它的路径,或者您可以简单地使用它的完整路径。对我来说,它位于文件夹C:\Program Files\Java\jdk1.8.0_31\bin中。请注意,您所需要做的就是通过–keep key 传递WSDL文件,该文件可通过链接远程访问,当然,除非我们禁用了 Web 服务。这些存根类是什么?他们只有两个人。其中之一是http:// ws.javarush.ru/
http://
wsimport -keep http://localhost:1986/wss/hello?wsdl
HelloWebService
,这本质上与我们在步骤 1 中手动创建的 Web 服务接口相同。区别很小,在于我们已经遇到的注释的使用方式略有不同,此外还使用了额外的注释,这我提到我什么都不知道,但既然以前没有它们,一切都对我们有用,那么它们显然不是强制性的。第二个类是stub HelloWebServiceImplService
,它继承自class Service
。我们已经在我们的客户端遇到过这个类Service
。我不会给出这个类的代码,因为...... 我还没准备好解释它的所有内容,但该类的本质归结为这样一个事实:我们之前在客户端中手动编写的用于连接到 Web 服务的所有内容都是在此类中自动创建的,我们只需要调用它的方法之一,我们将拥有镂空的一切。因此,让我们使用这些类在新项目中重写客户的代码,并确保代码更加简洁。首先,在新项目的src文件夹中,创建一个包ru.javarush.client
,并在其中创建一个HelloWebServiceClient
带有方法的类main
:
package ru.javarush.client;
// подключаем классы-заглушки
import ru.javarush.ws.*;
public class HelloWebServiceClient {
public static void main(String[] args) {
// подключаемся к тегу service в wsdl описании
HelloWebServiceImplService helloService = new HelloWebServiceImplService();
// получив информацию из тега service подключаемся к самому веб-сервису
HelloWebService hello = helloService.getHelloWebServiceImplPort();
// обращаемся к веб-сервису и выводим результат в консоль
System.out.println( hello.getHelloString("JavaRush Community") );
}
}
解析代码是基本的,我在注释中描述的内容已经足够了。启动客户端后,我们应该看到以下行:Hello, JavaRush Community!
同时,步骤 1 中的项目中的客户端将继续工作并显示我们在其中编写的文本,即:Hello, JavaRush!
此时,也许我们可以完成此操作一步,因为 他的目标已经达到了。我们意识到,如果有一个 Web 服务的WSDL描述,那么jdk就可以为我们提供自动生成stub
存根类的功能,以简化为该 Web 服务编写客户端的过程。在我看来,当您想要测试别人的 Web 服务而不是查看其WSDL描述时,这是一个非常有用的功能。 展望未来 在下一篇关于 Web 服务的文章中,我想概述如何将 Web 服务部署到 Tomcat servlet 容器和不同的应用程序服务器中,这样您就不需要将 Web 服务作为单独的应用程序,就像我们在前两个步骤中所做的那样。但在此之前,我认为最好先离题一下什么是 servlet、servlet 容器以及它们与应用程序服务器和常规 Web 有何不同……。此外,我们还必须对应用服务器进行简要概述,我认为这值得我们关注。
GO TO FULL VERSION