JavaRush /Blog Java /Random-ES /Servicios web. Paso 1. ¿Qué es un servicio web y cómo tra...
eGarmin
Nivel 41

Servicios web. Paso 1. ¿Qué es un servicio web y cómo trabajar con él?

Publicado en el grupo Random-ES
El título del tema es realmente una pregunta, porque... Yo mismo no sé qué es y por primera vez intentaré trabajar con ello en el marco de este artículo. Lo único que puedo garantizar es que el código que se presenta a continuación funcionará, pero mis frases serán solo suposiciones y conjeturas sobre cómo yo mismo entiendo todo esto. Entonces vamos... Servicios web.  Paso 1. ¿Qué es un servicio web y cómo trabajar con él?  - 1

Introducción

Necesitamos comenzar con por qué se creó el concepto de servicios web. Cuando apareció este concepto en el mundo, ya existían tecnologías que permitían que las aplicaciones interactuaran a distancia, donde un programa podía llamar a algún método en otro programa, que podía ejecutarse en una computadora ubicada en otra ciudad o incluso país. Todo esto se abrevia como RPC (Llamada a procedimiento remoto). Los ejemplos incluyen tecnologías CORBA y, para Java, RMI (invocación de método remoto). Y todo parece ir bien en ellos, especialmente en CORBA, porque... Puedes trabajar con él en cualquier lenguaje de programación, pero todavía faltaba algo. Creo que la desventaja de CORBA es que funciona a través de algunos de sus propios protocolos de red en lugar de un simple HTTP, que atravesará cualquier firewall. La idea del servicio web era crear un RPC que se insertaría en paquetes HTTP. Así comenzó el desarrollo de la norma. Cuáles son los conceptos básicos de esta norma:
  1. JABÓN . Antes de llamar a un procedimiento remoto, debe describir esta llamada en un archivo XML en formato SOAP. SOAP es simplemente uno de los muchos códigos XML que se utilizan en los servicios web. Todo lo que queremos enviar a algún lugar a través de HTTP primero se convierte en una descripción XML SOAP, luego se introduce en un paquete HTTP y se envía a otra computadora en la red a través de TCP/IP.
  2. WSDL . Hay un servicio web, es decir. un programa cuyos métodos se pueden llamar de forma remota. Pero el estándar requiere que este programa vaya acompañado de una descripción que diga que "sí, tienes razón: este es realmente un servicio web y puedes llamar a tales o cuales métodos desde él". Esta descripción está representada por otro archivo XML, que tiene un formato diferente, concretamente WSDL. Aquellos. WSDL es sólo un archivo XML que describe un servicio web y nada más.
¿Por qué preguntas tan brevemente? ¿No puedes ser más específico? Probablemente sea posible, pero para hacerlo tendrás que recurrir a libros como T. Mashnin, "Java Web Services". Allí, a lo largo de las primeras 200 páginas, se encuentra una descripción detallada de cada etiqueta de los estándares SOAP y WSDL. ¿Vale la pena hacerlo? En mi opinión no, porque... todo esto se crea automáticamente en Java, y solo necesitas escribir el contenido de los métodos que se supone que deben llamarse de forma remota. Entonces, apareció una API como JAX-RPC en Java. Si alguien no lo sabe, cuando dice que Java tiene tal o cual API, significa que hay un paquete con un conjunto de clases que encapsulan la tecnología en cuestión. JAX-RPC evolucionó con el tiempo de una versión a otra y finalmente se convirtió en JAX-WS. Obviamente, WS significa WebService y se podría pensar que se trata simplemente de un cambio de nombre de RPC como palabra de moda popular en estos días. Esto no es cierto, porque Ahora los servicios web se han alejado de la idea original y le permiten no solo llamar a métodos remotos, sino también simplemente enviar mensajes de documentos en formato SOAP. Todavía no sé por qué es necesario; es poco probable que la respuesta aquí sea "por si acaso es necesario". A mí mismo me gustaría aprender de camaradas más experimentados. Y por último, apareció JAX-RS para los llamados servicios web RESTful, pero este es el tema de un artículo aparte. La introducción puede terminar aquí, porque... A continuación aprenderemos a trabajar con JAX-WS.

Enfoque general

En los servicios web siempre hay un cliente y un servidor. El servidor es nuestro servicio web y a veces se le llama punto final (como en el punto final al que llegan los mensajes SOAP del cliente). Necesitamos hacer lo siguiente:
  1. Describe la interfaz de nuestro servicio web.
  2. Implementar esta interfaz
  3. Lanzar nuestro servicio web
  4. Escriba un cliente y llame de forma remota al método de servicio web deseado
Puede iniciar un servicio web de diferentes maneras: describir una clase con un método maine iniciar el servicio web directamente como un servidor, o implementarlo en un servidor como Tomcat o cualquier otro. En el segundo caso, nosotros mismos no iniciamos un nuevo servidor ni abrimos otro puerto en la computadora, sino que simplemente le decimos al contenedor de servlets Tomcat que “hemos escrito clases de servicios web aquí, publíquelas para que todos los que se comuniquen con usted puedan utilice nuestro servicio web." Independientemente del método de lanzamiento del servicio web, tendremos el mismo cliente.

Servidor

Iniciemos IDEA y creemos un nuevo proyecto Crear nuevo proyecto . Especifique el nombre HelloWebService y haga clic en el botón Siguiente y luego en el botón Finalizar . En la carpeta src crearemos el paquete ru.javarush.ws . En este paquete crearemos una interfaz HelloWebService:

package ru.javarush.ws;

// это аннотации, т.е. способ отметить наши классы и методы,
// Cómo связанные с веб-сервисной технологией
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

// говорим, что наш интерфейс будет работать Cómo веб-сервис
@WebService
// говорим, что веб-сервис будет использоваться для вызова методов
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface HelloWebService {
    // говорим, что этот метод можно вызывать удаленно
    @WebMethod
    public String getHelloString(String name);
}
En este código, las clases son las llamadas anotaciones WebServicey WebMethodno hacen nada más que marcar nuestra interfaz y su método como un servicio web. Lo mismo se aplica a la clase SOAPBinding. La única diferencia es que SOAPBindinges una anotación con parámetros. En este caso, se utiliza un parámetro stylecon un valor que indica que el servicio web no funcionará a través de mensajes de documentos, sino como un RPC clásico, es decir. para llamar a un método. Implementemos nuestra lógica de interfaz y creemos una clase en nuestro paquete HelloWebServiceImpl. Por cierto, observo que finalizar una clase con Impl es una convención en Java, según la cual la implementación de interfaces se designa así (Impl - de la palabra implementación, es decir, implementación). Esto no es un requisito y eres libre de nombrar la clase como quieras, pero los buenos modales lo exigen:

package ru.javarush.ws;

// таже anotación, что и при описании интерфейса,
import javax.jws.WebService;

// но здесь используется с параметром endpointInterface,
// указывающим полное Nombre класса интерфейса нашего веб-сервиса
@WebService(endpointInterface = "ru.javarush.ws.HelloWebService")
public class HelloWebServiceImpl implements HelloWebService {
    @Override
    public String getHelloString(String name) {
        // просто возвращаем приветствие
        return "Hello, " + name + "!";
    }
}
Lancemos nuestro servicio web como un servidor independiente, es decir. sin la participación de ningún Tomcat ni servidores de aplicaciones (este es un tema para una discusión aparte). Para ello, en la estructura del proyecto en la carpeta src , crearemos un paquete ru.javarush.endpoint, y en él crearemos una clase HelloWebServicePublishercon un método main:

package ru.javarush.endpoint;

// класс, для запуска веб-servidorа с веб-сервисами
import javax.xml.ws.Endpoint;
// класс нашего веб-сервиса
import ru.javarush.ws.HelloWebServiceImpl;

public class HelloWebServicePublisher {
    public static void main(String... args) {
        // запускаем веб-servidor на порту 1986
        // и по DIRECCIÓNу, указанному в первом аргументе,
        // запускаем веб-сервис, передаваемый во втором аргументе
        Endpoint.publish("http://localhost:1986/wss/hello", new HelloWebServiceImpl());
    }
}
Ahora ejecutemos esta clase presionando Shift+F10 . No aparecerá nada en la consola, pero el servidor se está ejecutando. Puede verificar esto escribiendo la línea http://localhost:1986/wss/hello?wsdl en su navegador . La página que se abre, por un lado, demuestra que tenemos un servidor web (http://) ejecutándose en el puerto 1986 de nuestro ordenador (localhost) y, por otro lado, muestra una descripción WSDL de nuestro servicio web. Si detiene la aplicación, la descripción dejará de estar disponible, al igual que el servicio web en sí, por lo que no haremos esto, sino que pasaremos a escribir el cliente.

Cliente

En la carpeta del proyecto src crearemos un paquete ru.javarush.clienty en él una clase HelloWebServiceClientcon un método main:

package ru.javarush.client;

// нужно, чтобы получить wsdl описание и через него
// дотянуться до самого веб-сервиса
import java.net.URL;
// такой эксепшн возникнет при работе с un objetoом 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, чтобы
        // получить ссылку на удаленный от нас un objeto веб-сервиса
        HelloWebService hello = service.getPort(HelloWebService.class);

        // Ура! Теперь можно вызывать удаленный метод
        System.out.println(hello.getHelloString("JavaRush"));
    }
}
Di el máximo de comentarios sobre el código en el listado. No tengo nada que agregar, así que ejecutemos (Shift+F10). Deberíamos ver el texto en la consola: Hello, JavaRush!Si no lo vio, probablemente olvidó iniciar el servicio web.

Conclusión

Este tema proporcionó una breve excursión a los servicios web. Una vez más, diré que gran parte de lo que escribí son mis suposiciones sobre cómo funciona y, por lo tanto, no debes confiar demasiado en mí. Agradecería que personas con conocimientos me corrigieran, porque así aprenderé algo. UPD. continuemos la conversación
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION