JavaRush /Java 博客 /Random-ZH /网页服务。步骤 1. 什么是 Web 服务以及如何使用它?
eGarmin
第 41 级

网页服务。步骤 1. 什么是 Web 服务以及如何使用它?

已在 Random-ZH 群组中发布
题目确实是个问题,因为…… 我自己也不知道它是什么,我将第一次尝试在本文的框架内使用它。我唯一可以保证的是下面提供的代码可以工作,但我的短语只是对我自己如何理解这一切的假设和猜测。那么,我们走吧... 网页服务。 步骤 1. 什么是 Web 服务以及如何使用它? - 1

介绍

我们需要从为什么创建 Web 服务的概念开始。当这个概念出现在世界上时,允许应用程序进行远距离交互的技术已经存在,其中一个程序可以调用另一个程序中的某种方法,该程序可以在位于另一个城市甚至国家的计算机上启动。所有这些都缩写为 RPC(远程过程调用)。示例包括 CORBA 技术和 Java 的 RMI(远程方法调用)。他们似乎一切都很好,尤其是 CORBA,因为…… 您可以使用任何编程语言来使用它,但仍然缺少一些东西。我认为 CORBA 的缺点是它通过自己的一些网络协议而不是简单的 HTTP 工作,而 HTTP 可以通过任何防火墙。Web 服务的想法是创建一个将插入到 HTTP 数据包中的 RPC。由此开始了标准的开发。该标准的基本概念是什么:
  1. 肥皂。在调用远程过程之前,您需要在 SOAP 格式的 XML 文件中描述此调用。SOAP 只是 Web 服务中使用的众多 XML 标记之一。我们想要通过 HTTP 发送到某处的所有内容首先都会转换为 XML SOAP 描述,然后填充到 HTTP 数据包中并通过 TCP/IP 发送到网络上的另一台计算机。
  2. WSDL。有一个网络服务,即 其方法可以被远程调用的程序。但该标准要求该程序附有一个描述,内容是“是的,你是对的 - 这确实是一个 Web 服务,你可以从中调用这样那样的方法。” 该描述由另一个 XML 文件表示,该文件具有不同的格式,即 WSDL。那些。WSDL 只是一个描述 Web 服务的 XML 文件,仅此而已。
为什么你问得这么简短?不能说得具体一点吗?这可能是可能的,但要做到这一点,您必须查阅 T. Mashnin 的《Java Web Services》等书籍。其中前 200 页详细描述了 SOAP 和 WSDL 标准的每个标签。值得做吗?在我看来,不,因为... 所有这些都是Java自动创建的,你只需要编写应该远程调用的方法的内容。于是,Java中出现了JAX-RPC这样的API。如果有人不知道,当他们说 Java 有这样那样的 API 时,这意味着有一个包含一组类的包封装了相关技术。JAX-RPC 随着时间的推移从一个版本演变到另一个版本,最终成为 JAX-WS。WS 显然代表 WebService,您可能会认为这只是当今流行术语 RPC 的重命名。这不是真的,因为 现在,Web 服务已经偏离了最初的想法,不仅允许您调用远程方法,还允许您简单地以 SOAP 格式发送文档消息。我还不知道为什么需要这样做;这里的答案不太可能是“以防万一需要”。我自己也想向更有经验的同志学习。最后,JAX-RS 出现了,用于所谓的 RESTful Web 服务,但这是另一篇文章的主题。介绍到这里就可以结束了,因为…… 接下来我们将学习如何使用 JAX-WS。

一般的做法

在 Web 服务中始终存在客户端和服务器。服务器是我们的 Web 服务,有时称为端点(例如,来自客户端的 SOAP 消息到达的端点)。我们需要执行以下操作:
  1. 描述我们网络服务的界面
  2. 实现这个接口
  3. 启动我们的网络服务
  4. 编写客户端并远程调用所需的Web服务方法
您可以通过不同的方式启动 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);
}
在这段代码中,这些类就是所谓的注释WebServiceWebMethod除了将我们的接口及其方法标记为 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 服务。

结论

本主题简要介绍了 Web 服务。我再说一遍,我写的大部分内容都是我对其工作原理的猜测,因此你不应该太相信我。如果有知识的人纠正我,我将不胜感激,因为那样我会学到一些东西。 UPD。 让我们继续对话
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION