题目确实是个问题,因为…… 我自己也不知道它是什么,我将第一次尝试在本文的框架内使用它。我唯一可以保证的是下面提供的代码可以工作,但我的短语只是对我自己如何理解这一切的假设和猜测。那么,我们走吧...
介绍
我们需要从为什么创建 Web 服务的概念开始。当这个概念出现在世界上时,允许应用程序进行远距离交互的技术已经存在,其中一个程序可以调用另一个程序中的某种方法,该程序可以在位于另一个城市甚至国家的计算机上启动。所有这些都缩写为 RPC(远程过程调用)。示例包括 CORBA 技术和 Java 的 RMI(远程方法调用)。他们似乎一切都很好,尤其是 CORBA,因为…… 您可以使用任何编程语言来使用它,但仍然缺少一些东西。我认为 CORBA 的缺点是它通过自己的一些网络协议而不是简单的 HTTP 工作,而 HTTP 可以通过任何防火墙。Web 服务的想法是创建一个将插入到 HTTP 数据包中的 RPC。由此开始了标准的开发。该标准的基本概念是什么:- 肥皂。在调用远程过程之前,您需要在 SOAP 格式的 XML 文件中描述此调用。SOAP 只是 Web 服务中使用的众多 XML 标记之一。我们想要通过 HTTP 发送到某处的所有内容首先都会转换为 XML SOAP 描述,然后填充到 HTTP 数据包中并通过 TCP/IP 发送到网络上的另一台计算机。
- WSDL。有一个网络服务,即 其方法可以被远程调用的程序。但该标准要求该程序附有一个描述,内容是“是的,你是对的 - 这确实是一个 Web 服务,你可以从中调用这样那样的方法。” 该描述由另一个 XML 文件表示,该文件具有不同的格式,即 WSDL。那些。WSDL 只是一个描述 Web 服务的 XML 文件,仅此而已。
一般的做法
在 Web 服务中始终存在客户端和服务器。服务器是我们的 Web 服务,有时称为端点(例如,来自客户端的 SOAP 消息到达的端点)。我们需要执行以下操作:- 描述我们网络服务的界面
- 实现这个接口
- 启动我们的网络服务
- 编写客户端并远程调用所需的Web服务方法
main
并直接将 Web 服务作为服务器启动,或者将其部署到 Tomcat 或任何其他服务器等服务器。第二种情况,我们自己不启动新的服务器,也不在计算机上打开另一个端口,而只是简单地告诉 Tomcat servlet 容器“我们在这里编写了 Web 服务类,请发布它们,以便每个与您联系的人都可以”使用我们的网络服务。” 无论采用何种方法启动 Web 服务,我们都将拥有相同的客户端。
服务器
让我们启动 IDEA 并创建一个新项目Create New Project。指定名称HelloWebService并单击“下一步”按钮,然后单击“完成”按钮。在src文件夹中,我们将创建包ru.javarush.ws。在此包中,我们将创建一个接口HelloWebService
:
package ru.javarush.ws;
// это аннотации, т.е. способ отметить наши классы и методы,
// How связанные с веб-сервисной технологией
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
// говорим, что наш интерфейс будет работать How веб-сервис
@WebService
// говорим, что веб-сервис будет использоваться для вызова методов
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface HelloWebService {
// говорим, что этот метод можно вызывать удаленно
@WebMethod
public String getHelloString(String name);
}
在这段代码中,这些类就是所谓的注释WebService
,WebMethod
除了将我们的接口及其方法标记为 Web 服务之外什么也不做。这同样适用于班级SOAPBinding
。唯一的区别是SOAPBinding
它是带有参数的注释。在这种情况下,使用一个参数style
和一个值来指示 Web 服务将不通过文档消息工作,而是作为经典 RPC,即 调用一个方法。让我们实现我们的接口逻辑并在我们的包中创建一个类HelloWebServiceImpl
。顺便说一句,我注意到以 Impl 结尾类是 Java 中的一种约定,根据该约定,接口的实现是这样指定的(Impl - 来自“实现”一词,即实现)。这不是必需的,您可以随意命名该类,但良好的举止需要这样做:
package ru.javarush.ws;
// таже annotation, что и при описании интерфейса,
import javax.jws.WebService;
// но здесь используется с параметром endpointInterface,
// указывающим полное Name класса интерфейса нашего веб-сервиса
@WebService(endpointInterface = "ru.javarush.ws.HelloWebService")
public class HelloWebServiceImpl implements HelloWebService {
@Override
public String getHelloString(String name) {
// просто возвращаем приветствие
return "Hello, " + name + "!";
}
}
让我们将我们的 Web 服务作为独立服务器启动,即 无需任何 Tomcat 和应用程序服务器的参与(这是一个单独讨论的主题)。为此,在src文件夹的项目结构中,我们将创建一个包ru.javarush.endpoint
,并在其中创建一个HelloWebServicePublisher
带有方法的类main
:
package ru.javarush.endpoint;
// класс, для запуска веб-serverа с веб-сервисами
import javax.xml.ws.Endpoint;
// класс нашего веб-сервиса
import ru.javarush.ws.HelloWebServiceImpl;
public class HelloWebServicePublisher {
public static void main(String... args) {
// запускаем веб-server на порту 1986
// и по addressу, указанному в первом аргументе,
// запускаем веб-сервис, передаваемый во втором аргументе
Endpoint.publish("http://localhost:1986/wss/hello", new HelloWebServiceImpl());
}
}
现在让我们按Shift+F10来运行这个类。控制台中不会出现任何内容,但服务器正在运行。您可以通过在浏览器中输入http://localhost:1986/wss/hello?wsdl行来验证这一点。打开的页面一方面证明我们有一个 Web 服务器 (http://) 在我们的计算机 (localhost) 上的端口 1986 上运行,另一方面显示了我们的 Web 服务的 WSDL 描述。如果停止应用程序,描述将变得不可用,Web 服务本身也将变得不可用,因此我们不会这样做,而是继续编写客户端。
客户
在项目文件夹src中,我们将创建一个包ru.javarush.client
,并在其中创建一个HelloWebServiceClient
带有方法的类main
:
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"));
}
}
我对清单中的代码给出了最多的评论。我没有什么要添加的,所以让我们运行(Shift+F10)。我们应该在控制台中看到文本:Hello, JavaRush!
如果您没有看到它,那么您可能忘记启动 Web 服务。
GO TO FULL VERSION