Java llama WebService. Cuando se ponga en contacto por primera vez, pensará que es una pesadilla, especialmente sin una implementación estándar unificada. En comparación con la implementación del servicio web que se puede completar en unos pocos pasos de .NET, es realmente triste ver la implementación de Java. Pero incluso si estamos tristes, todavía tenemos que completarlo. Java también tiene muchas buenas implementaciones, como Xfire, Jersey, CXF. Aquí echaremos un vistazo a la implementación de XFire juntos.
1) En primer lugar, por supuesto que tengo que salir de la bolsa, y esta persona común lo sabe. http://xfire.codehaus.org/download puede ir aquí, puede ir todo o distribución. Pero es mejor darle muchos problemas extraños para perder confianza.
¿Qué debo hacer si me quito la bolsa? Ponlo en el proyecto. Parece tonterías, pero muchas personas simplemente no saben qué hacer.
Para construir un nuevo proyecto, lo comparo con XfireWebService, que, por supuesto, es un proyecto web aquí.
He puesto todos sus paquetes aquí. Después de todo, cuando escribimos ejemplos, no hay necesidad de ser exigente. Haga clic casualmente. Si desea ver la información de excepción, puede agregarla lentamente. Es fácil eliminar los errores en el futuro, pero no lo haremos aquí. Después de todo, no hay nada feo en la falta de ningún tipo de excepciones, y puedes eliminarlas tú mismo.
2) Entendamos primero la diferencia entre XFIR y otros marcos de servicio web. La mayor diferencia es que requiere una interfaz, y si necesita usar xfire para llamar al servicio web correspondiente, debe conocer la definición de la interfaz. Siento que hay un poco de limitación aquí. Pero aparte de esto, es bastante conveniente llamar al servicio web, al igual que llamar a los métodos locales. Echemos un vistazo al ejemplo directamente:
En primer lugar, la interfaz más importante:
interfaz pública IReaderservice {public lector getReader (nombre de cadena, contraseña de cadena); Lista pública <Re Reader> getReaders (); } Hay una interfaz, por supuesto, debe haber una clase de implementación, de lo contrario, la interfaz no tendrá sentido. Public Class ReaderService implementa IReaderservice {public lector getReader (nombre de cadena, contraseña de cadena) {return New Reader (nombre, contraseña); } Public List <Re Reader> getReaders () {List <Re Reader> ReaderList = New ArrayList <Reader> (); ReaderList.Add (nuevo lector ("shun1", "123")); ReaderList.Add (nuevo lector ("shun2", "123")); return ReaderList; }} También eche un vistazo a las clases de Javabean y Reader:
Lector de clase pública {Private static final Long SerialVersionUid = 1L; nombre de cadena privada; contraseña de cadena privada; public lerer () {} public lector (nombre de cadena, contraseña de cadena) {this.name = name; this.password = contraseña; } // get/set Method omite public String toString () {return "name:"+name+", contraseña:"+contraseña; }}Tenga en cuenta que nuestra clase de lector aquí implementa la interfaz serializable, ¿por qué? Aquí, en primer lugar, necesitamos comprender el principio del servicio web. Para Java, si necesitamos cargar objetos en Internet, muchas personas, por supuesto, pensarán en la serialización. Por cierto, esto es serialización, porque necesitamos pasar al lector como parámetro. Esto debe implementarse por la fuerza en la versión anterior, de lo contrario se informará un error. Sin embargo, la última versión (de hecho, la última también es de 2007, porque XFIRS ha dejado de desarrollarse y Apache ha fusionado en un proyecto CXF. Ya no es necesario hablar sobre esto). En cuanto a cómo implementarlo, no lo investigaremos en profundidad aquí por el momento, porque se ha fusionado en CXF. Si queremos aprender en profundidad, debería ser mejor aprender CXF.
3) Después de completar la interfaz anterior y la escritura de Javabean, muchas personas preguntarán, veo que muchos servicios web tendrán archivos WSDL, entonces, ¿cómo lo obtuviste? Antes de hablar sobre esto, discutamos qué es WSDL. Quizás muchas compañías proporcionan interfaces que son solo direcciones HTTP, que devuelven formatos XML, y también lo son nuestras. Esto tiene una ventaja y una desventaja. La ventaja es que nuestro desarrollo es menos difícil, mientras que la desventaja es que necesitamos proporcionar a los usuarios un montón de archivos de explicación. ¿Qué significa cada etiqueta XML devuelta? Esto no es nada, pero es solo molesto. En cuanto al servicio web, la desventaja es que hemos desarrollado un poco más de cosas, y la ventaja es que no tenemos que escribir tantos archivos de explicación, porque hay una explicación unificada llamada WSDL. Este es el documento de explicación del servicio web, que está unificado y lo mismo sin importar qué idioma, por lo que no hay problema que nadie pueda entender.
Y aquí, cuando implementamos xfire, puede ayudarnos a generar archivos WSDL.
El problema es cómo implementarlo, esto es realmente simple. Creamos una nueva carpeta Meta-INF en el directorio SRC, y luego creamos una carpeta XFIRE en ella y creamos el archivo Services.xml. La estructura posterior es la siguiente:
Algunas personas pueden preguntar por qué necesitamos incorporarlo en el directorio SRC. De hecho, no es una construcción prescrita aquí, sino porque necesitamos pedirle a las herramientas de desarrollo que nos ayuden a implementar estos archivos nosotros mismos, por lo que si lo ponemos aquí, Eclipse puede ayudarnos a implementarlo en Tomcat u otros contenedores nosotros mismos. Tenga en cuenta que el nivel de carpeta donde se encuentra este archivo se fija y no se puede modificar.
Echemos un vistazo a los servicios.xml directamente:
<? xml versión = "1.0" encoding = "utf-8"?> <beans xmlns = "http://xfire.codehaus.org/config/1.0"> <service> <!-El nombre de la oferta de WebServiceq, necesita especificar esto al llamar-> <name> ReaderService </name> <!-Esto suele ser la dirección del sitio web, y no tiene mucho sentido. <Pace> http: // test/helloService </amespace> <!-Interface Class-> <ServiceClass> com.xfire.servlet.ireaderservice </ServiceClass> <!-Clase de implementación-> <ImplementationClass> com.xfire.servlet.service de servicio </implementationclass> </secedge> </serv>
En general, está bien mirar los comentarios.
4) Muchas personas piensan que esto es suficiente. No, aún no ha funcionado. Si especifica esto, ¿cómo pueden otros visitarlo? Cómo reenviar la solicitud correspondiente a xfire y dejar que la procese. Necesitamos modificar el Web.xml nuevamente.
Después de la modificación, lo siguiente es:
<? xml versión = "1.0" encoding = "utf-8"?> <web-app xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns = "http://java.sun.com/xml/ns/javaee" " xmlns: web = "http://java.sun.com/xml/ns/javaee" xmlns: web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi: schemalocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id = "webapp_id" version = "3.0"> <ervlet> <ervlet-name> xfirreservlet </servlet </servlet </servlet </servlet> <Servlet-Class> org.codehaus.xfire.transport.http.xfiConfigurableServlet </servlet-class> </servlet> <ervlet-mapping> <ervlet-name> xfirreServlet </servlet-name> <url-pattern>/servicios/*</url-pattern> </servlet-mappes> </web-papp>
De hecho, solo está agregando un servlet y el mapeo correspondiente. A continuación, lo ingresamos directamente en el navegador:
http: // localhost: 8080/xfireWebService/Services/Readerservice? WSDL
Podemos ver:
Lo que se muestra aquí es WSDL, que mostrará el método que definimos y el tipo devuelto. Hay una explicación de WSDL más tarde.
5) Después de completar los cuatro pasos anteriores, hemos completado la implementación del servicio web. Otros pueden llamar al servicio web correspondiente para acceder a nuestros métodos. Usemos el cliente proporcionado por XFIRE para acceder al servicio del sitio web que acabamos de publicar:
Public Class ReadClient {public static void main (String [] args) {// Aquí es crear un servicio, y se debe pasar una clase de interfaz, porque debemos llamar al servicio de método de interfaz correspondiente srcModel = new ObjectServiceFactory (). Create (Ireaderservice.class); // Agent Factory, aquí es crear la clase de interfaz correspondiente más tarde xfireproxyfactory fábrica = new XFireProxyFactory (xfireFactory.newinstance (). Getxfire ()); // Dirección de servicio web, no es necesario agregar WSDL String ReaderserviceUrl = "http: // localhost: 8080/xfirewebservice/services/readerservice"; Pruebe {// Use la fábrica para devolver la clase de interfaz correspondiente IReaderservice Readerservice = (IReaderservice) Factory.Create (SrcModel, ReaderserviceUrl); Lector lector = readerservice.getReader ("shun", "123"); System.out.println (lector); } catch (malformedurexception e) {E.PrintStackTrace (); }}} De esta manera, vemos que la salida es:
Análisis de la estructura de archivos WSDL
WSDL (lenguaje de descripción de servicios web, idioma de descripción del servicio web) es una aplicación XML que define una descripción del servicio web como un conjunto de puntos de acceso al servicio a través de los cuales los clientes pueden acceder a los servicios que contienen información de documentos o llamadas de procedimiento (similar a las llamadas de procedimientos remotos). WSDL primero resume la operación de acceso y el mensaje de solicitud/respuesta utilizado durante el acceso, y luego lo une a un protocolo de transporte específico y formato de mensaje para definir en última instancia el punto de acceso de servicio implementado específico. Los puntos de acceso al servicio para implementaciones específicas relacionadas se convierten en servicios web abstractos a través de la combinación. Este artículo explicará la estructura del documento WSDL en detalle y analizará el papel de cada elemento.
1: definición de WSDL
WSDL es un documento utilizado para describir con precisión los servicios web, y un documento WSDL es un documento XML que sigue al patrón WSDL XML. El documento WSDL define un servicio web como una colección de puntos de acceso de servicio o puertos. En WSDL, dado que la definición abstracta de los puntos y mensajes de acceso al servicio se ha separado de la implementación del servicio específica o la vinculación del formato de datos, la definición abstracta se puede usar nuevamente: el mensaje se refiere a una descripción abstracta de los datos intercambiados; y el tipo de puerto se refiere a una colección abstracta de operaciones. Protocolos específicos y especificaciones de formato de datos para tipos de puertos específicos constituyen un enlace que se puede reutilizar. Asociando una dirección de acceso web con una vinculación reutilizable, se puede definir un puerto y una colección de puertos se define como un servicio.
Un documento WSDL generalmente contiene 7 elementos importantes, a saber, tipos, importación, mensaje, porttype, operación, vinculación y elementos de servicio. Estos elementos están anidados en el elemento Definiciones, que es el elemento raíz del documento WSDL. La siguiente parte del artículo presentará la estructura básica de WSDL en detalle.
2: Estructura básica de WSDL-Overview
Como se describe al final de la primera parte, un documento básico de WSDL contiene 7 elementos importantes. Lo siguiente introducirá estos elementos y sus funciones.
El documento WSDL utiliza los siguientes elementos en la definición de un servicio web:
・ Tipos: un contenedor definido por un tipo de datos, que utiliza un sistema de tipo determinado (generalmente el sistema de tipos en el esquema XML).
・ Mensaje - Definición de tipo abstracto de estructuras de datos para mensajes de comunicación. Use los tipos definidos por los tipos para definir la estructura de datos de todo el mensaje.
・ Operación: una descripción abstracta de las operaciones admitidas en el servicio. En general, una sola operación describe un par de mensajes de solicitud/respuesta que accede a la entrada.
・ Porttype: una colección abstracta de operaciones compatibles con un determinado tipo de punto de entrada de acceso, que puede ser compatible con uno o más puntos de acceso de servicio.
・ Enlace: enlace de protocolos específicos y especificaciones de formato de datos para tipos de puertos específicos.
・ Puerto: definido como un único punto de acceso de servicio que combina el enlace de protocolo/formato de datos con direcciones de acceso web específicas.
・ Servicio: una colección de puntos de acceso de servicio relacionados.
El esquema XML de WSDL se puede denominar la siguiente URL: http://schemas.xmlsoap.org/wsdl/
Tres: Estructura básica de WSDL-Descripción detallada
Esta sección describirá en detalle el papel de cada elemento del documento WSDL a través de un ejemplo. El siguiente ejemplo es el contenido de un documento WSDL simple. Para la generación de este documento, consulte mi otro artículo: Ejemplo de desarrollo de XFIRS--ALLADOR.
Un documento WSDL de servicio web simple que admite una operación única llamada Sayhello, que se implementa ejecutando el protocolo SOAP en HTTP. La solicitud acepta un nombre de cadena y devuelve una cadena simple después del procesamiento. La documentación es la siguiente:
<? xml versión = "1.0" encoding = "utf-8"?> <wsdl: definiciones targetNamespace = "http: //com.liuxiang.xfiredemo/helloService" xmlns: tns = "http: //com.liuxiang.xfiredemo/helloService" "" xmlns: wsdlsoap = "http://schemas.xmlsoap.org/wsdl/soap/" xmlns: soap12 = "http://www.w3.org/2003/05/soap-envelope" xmlns: xsd = "http://www.w3.org/2001/xmlschema" xmlns: soapenc11 = "http://schemas.xmlsoap.org/soap/encoding/" XMLNS: SOAPENC12 = "http://www.w3.org/2003/05/soap-coding" xmlns: soap11 = "http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <wsdl:types> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" TargetNamesPace = "http: //com.liuxiang.xfiredemo/helloService"> <xsd: elemento name = "sayhello"> <xsd: complextype> <xsd: secuencia> <xsd: elemento maxoccurs = "1" minoccurs = "1" name = "nillable =" true "type =" xsd: striet "/> striet"/> striet "/>/>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sil </xsd: secuencia> </xsd: complextype> </xsd: elemento> <xsd: elemento name = "sayhellorSponse"> <xsd: complextype> <xsd: secuence> <xsd: elemento maxoccurs = "1" minecUncurs = "1" name = "out" nillable = "type =" type = "xsd: string"/</xsd: secter: xsd: secter: section: secter: secter: section: section: section: section: secter: section: secter: secter: section: secter: secter: shatence; </xsd: complextype> </xsd: elemento> </xsd: esquema> </wsdl: tipos> <wsdl: mensaje name = "sayhelloresponse"> <wsdl: parte name = "parámetros" elemento = "tns: sayhellorSponse"/> </wsdl: mensaje> <wsdl: mensaje = "sayhelleStest" <wsdl: parte name = "parámetros" element = "tns: sayhello" /> < /wsdl: mensaje> <wsdl: porttype name = "helloserviceporttype"> <wsdl: operation name = "sayhello"> <wsdl: input name = "sayhellorequest" Message = "tns: sayhellorequest" /outen name = "sayHellorSponse" Message = "tns: sayhellorSponse"/> </wsdl: operation> </wsdl: porttype> <wsdl: binding name = "helloserviceHttpbinding" type = "tns: helloServicePortType"> <wsdlsoap: binking style = "documento" "documento" "documento" "" Documento "" "Documento" " transport = "http://schemas.xmlsoap.org/soap/http"/> <wsdlsoap: operation name = "sayhello"> <wsdlsoap: operation soapaction = ""/> <wsdlsoap: operatoraction = "/> <wsdlsoap: body use =" literal "/> <wsdl: wsdl <wsdlsoap: body usse = "literal"/> </wsdl: output> </wsdl: operation> </wsdl: binding> <wsdl: service name = "helloService"> <wsdl: puerto name = "helloserviceHttpport" binding = "tns: helloservicehtpbinding"> <wservicehtpport: dirección "binding =" tns: helloservicehtpbinding "> <wservicehtport: dirección de la dirección: binde. ubicación = "http: // localhost: 8080/xfire/services/helloService"/> </wsdl: puerto> </wsdl: servicio> </wsdl: definiciones>
El elemento Tipos utiliza el lenguaje de esquema XML para declarar tipos de datos y elementos complejos utilizados en otras partes del documento WSDL;
El elemento de importación es similar al elemento de importación en un documento de esquema XML y se utiliza para importar definiciones WSDL de otros documentos WSDL;
El elemento de mensaje describe la carga útil de un mensaje utilizando el tipo incorporado, el tipo complejo o el elemento del esquema XML definido en el elemento de tipo del documento WSDL o definido en el documento WSDL externo referenciado por el elemento de importación;
El elemento PortType y el elemento de operación describen la interfaz del servicio web y definen sus métodos. El elemento PortType y el elemento de operación son similares a la declaración del método definida en la interfaz Java. El elemento de operación utiliza uno o más tipos de mensajes para definir la carga útil de su entrada y salida;
El elemento de enlace asigna el elemento PortType y el elemento de operación a un protocolo especial y estilo de codificación;
El elemento de servicio es responsable de asignar la dirección de Internet a un enlace específico;
1. Definiciones elementos
El elemento raíz de todos los documentos WSDL es un elemento de definiciones. Este elemento encapsula todo el documento mientras proporciona un documento WSDL a través de su nombre. Este elemento no tiene otra función, excepto proporcionar un espacio de nombres, por lo que no se describirá en detalle.
El siguiente código es la estructura de un elemento de definiciones:
<wsdl: definiciones TargetNamesPace = "http: //com.liuxiang.xfiredemo/helloservice" xmlns: tns = "http: //com.liuxiang.xfiredemo/helloservice" xmlns: wsdlsoap = "http://schemas.xmlsoap.org/wsdl/soap/" xmlns: soap12 = "http://www.w3.org/2003/05/soap-envelope" xmlns: xsd = "http://www.w3.org/2001/xmlschema" xmlns: soapenc11 = "http://schemas.xmlsoap.org/soap/encoding/" XMLNS: SOAPENC12 = "http://www.w3.org/2003/05/soap-coding" xmlns: soap11 = "http://schemas.xmlsoap.org/soap/envelope/" xmlns: wsdl = "http://schemas.xmlsoap.org/wsdl/"> </wsdl: definiciones>
2. Tipos de elementos
WSDL adopta los tipos incorporados de esquema XML W3C como su sistema de tipo básico. El elemento tipos se usa como un contenedor para definir varios tipos de datos no descritos en los tipos de esquema XML. Al declarar la carga útil de la parte del mensaje, la definición del mensaje utiliza los tipos de datos y los elementos definidos en el elemento de tipo. Definiciones de tipos en este documento WSDL:
<wsd: tipos> <xsd: esquema xmlns: xsd = "http://www.w3.org/2001/xmlschema" atributeFormDefault = "calificado" elementformDefault = "calificado" TargetNamesPace = "http: //com.liuxiang.xfired" name = "sayhello"> <xsd: complextype> <xsd: secuence> <xsd: elemento maxoccurs = "1" MinOccurs = "1" name = "name" nillable = "true" type = "xsd: string"/> </xsd: secuencia> </xsd: complextype> </xsd: elemento> <xsd: el elemento name " <xsd: complextype> <xsd: secuence> <xsd: element maxoccurs = "1" minoccurs = "1" name = "out" nillable = "true" type = "xsd: string"/> </xsd: secuence> </xsd: complextype> </xsd: elemento> </xsd: schema> </wsdl: tipos> tipos>
Lo anterior es la parte de definición de datos, que define dos elementos, uno es Sayhello y el otro es SayhellorSponse:
Sayshello: define un tipo complejo que solo contiene una cadena simple, que se usa para describir la parte entrante de la operación en el futuro;
SayshellorSponse: define un tipo complejo que solo contiene una cadena simple, y el valor de retorno utilizado para describir la operación en el futuro;
3. Elementos de importación
El elemento de importación permite el uso de los elementos de definición en el espacio de nombres especificado en otros documentos WSDL en el documento WSDL actual. El elemento de importación no se usa en este ejemplo. Esta función suele ser muy efectiva cuando los usuarios desean modularizar documentos WSDL.
El formato de importación es el siguiente:
<wsdl: importación de nombres = "http://xxx.xxx.xxx/xxx/xxx" ubicación = "http://xxx.xxx.xxx/xxx/xxx.wsdl"/>>
Debe haber un atributo de espacio de nombres y un atributo de ubicación:
Atributo del espacio de nombres: el valor debe coincidir con el espacio de nombre de Target Names declarado en el documento WSDL que se está importando;
Atributo de ubicación: debe apuntar a un documento WSDL real, y el documento no puede estar vacío.
4. Elementos de mensajes
El elemento de mensaje describe la carga útil de un servicio web usando mensajes. El elemento de mensaje puede describir la carga útil de la salida o el mensaje de aceptación; También puede describir el contenido del encabezado del archivo SOAP y el elemento de detalle de error. La forma en que se define el elemento del mensaje depende del uso del estilo RPC o la mensajería de estilo de documento. En la definición del elemento de mensaje en este artículo, este documento utiliza mensajes de estilo de documento:
<wsdl: mensaje name = "sayhellorSponse"> <wsdl: parte name = "parámetros" elemento = "tns: sayhellorSponse" /> < /wsdl: mensaje> <wsdl: mensaje name = "sayhellorequest"> <wsdl: parte name = "parameters" element = "tns: sayhello" /> <<wsdl
Esta parte es una definición abstracta del formato de mensaje: se definen dos mensajes SayhellorSponse y Sayhellorequest:
Sayshellorequest: el formato de mensaje de solicitud de la operación Sayhello, que consiste en un fragmento de mensaje, los parámetros nombrados, y el elemento es el elemento en el tipo que definimos anteriormente;
SayshellorSponse: el formato de mensaje de respuesta de la operación Sayhello se compone de un fragmento de mensaje, parámetros nombrados, y el elemento es el elemento en los tipos que definimos anteriormente;
Si usa mensajes de estilo RPC, solo necesita modificar el elemento del elemento en el documento para escribir.
5. Elemento Porttype
El elemento PortType define la interfaz abstracta del servicio web. Esta interfaz es un poco similar a las interfaces Java, que definen un tipo y método abstracto, y no se define ninguna implementación. En WSDL, el elemento PortType se implementa mediante elementos vinculantes y de servicio, que se utilizan para ilustrar el protocolo de Internet, el esquema de codificación y la dirección de Internet utilizada por la implementación del servicio web.
Se pueden definir múltiples operaciones en un Porttype, y una operación puede considerarse como un método. La definición del documento WSDL en este artículo:
<wsdl:portType name="HelloServicePortType"> <wsdl:operation name="sayHello"> <wsdl:input name="sayHelloRequest" message="tns:sayHelloRequest" /> <wsdl:output name="sayHelloResponse" message="tns:sayHelloResponse" /> </wsdl:operation> </wsdl: porttype>
PortType define el tipo de modo de llamada del servicio. Contiene un método Operation Sayshello, que contiene entrada y salida para indicar que la operación es un modo de solicitud/respuesta. El mensaje de solicitud es el Sayhellorequest definido anteriormente, y el mensaje de respuesta es el SayhellorSponse definido anteriormente. La entrada representa la carga útil entregada al servicio web, y el mensaje de salida representa la carga útil entregada al cliente.
6. Atinguidad
El elemento de unión mapea un porttype abstracto a un conjunto de protocolos específicos (SOAO y HTTP), estilos de mensajería y estilos de codificación. Por lo general, los elementos de unión se usan junto con los elementos patentados del protocolo. Ejemplos en este artículo:
<wsdl: binding name = "helloserviceHttpBinding" type = "tns: helloserviceporttype"> <wsdlsoap: binding style = "document" transport = "http://schemas.xmlsoap.org/soapp.http"/> <wsdl: operación name = "Sayhello" <wsdlOs. SOAPACTION = "" /> <wsdl: input name = "sayhellorequest"> <wsdlsoap: corporal use = "literal" /> < /wsdl: input> <wsdl: name de salida = "sayhellorSponse"> <wsdlsoap: uso del cuerpo = "literal" /> </wsdl: salida>