lunes, 8 de octubre de 2012

Exponer servicios Grails a través de SOAP con CXF

Una de las facilidades de Grails es que tiene plugins para casi todo. Y uno de los mejores a la hora de exponer servicios web de tipo SOAP es el CXF plug-in for Grails. La única dependencia que teneis que añadir a vuestro BuildConfig es,
compile ":cxf:0.9.0"
Con esta línea, cuando arranqueis vuestra aplicación otra vez, te instalará el plugin. La instalación ya te meterá las librerías necesarias de CXF. La última versión que han sacado ya es compatible para Grails 2.
Para configurarlo se puede hacer de dos formas diferentes:

1. Con la propiedad estática "expose" igual a "cxf"
class TestService {

  static expose=['cxf'] 
  static exclude=["ignoredMethod"]

  boolean serviceMethod(YourDomainClass dc){ return true; }

  boolean ignoredMethod() { return "you shouldn't see me" }

}
Si queremos que algún método del servicio sea ignorado y no se exponga lo declararemos con la propiedad estática "exclude" y el nombre del método.
Todos los métodos que no estén en el exclude serán expuestos y serán accesibles para terceros a través de su url "http://127.0.0.1:8080/nombreApp/services/miServicio?wsdl"
Todas las clases de dominio que sean pasadas o devueltas como parámetros en los servicios web deberán llevar la anotación JAXB @XmlAccessorType(XmlAccessType.FIELD). Esto hará que todos los campos públicos y privados sean serializables. Más info de las anotaciones JAXB aquí.
@XmlAccessorType(XmlAccessType.FIELD)
class YourDomainClass {
  ...
}

2. Con la propiedad estática "expose" igual a "cxfjax". Configurado esto, ya podemos utilizar las anotaciones JaxWS para tener más control sobre tu WSDL.
import javax.jws.*

class TestService { static expose=['cxfjax']

  @WebResult(name="addResult") 
  @WebMethod(operationName="add") 
  int add(@WebParam(name="a")int a, @WebParam(name="b")int b) { 
    return a + b 
  } 
}
Con cxfjax, tienes que poner la anotación @WebMethod en el método del servicio que quieres exponer. Con la anotación @WebResult, le decimos el nombre del parámetro que devuelve el servicio en el WSDL y con @WebParam definimos el nombre del parámetro de entrada que está definido en el WSDL.

Anotaciones de JAXWS:
- @WebService indica que una clase Java está implementando un servicio Web o indica que una SEI (Service Endpoint Interface) está implementando una interfaz de servicio Web. Destino de anotación: Type. Parámetros que permite:

name="" -> El nombre de wsdl:portType. El valor por omisión es el nombre sin calificar de la interfaz o clase Java. (String)

targetNamespace="" -> Especifica el espacio de nombres XML o los elementos WSDL y XML generados a partir del servicio Web. El valor por omisión es el espacio de nombres correlacionado a partir del nombre del paquete que contiene el servicio Web. (String)

serviceName="" -> Especifica el nombre de servicio del servicio Web: wsdl:service. El valor por omisión es el nombre sencillo de la clase java más Service. (String)

endpointInterface="" -> Especifica el nombre calificado de la interfaz de punto final de servicio que define el contrato de servicio web abstracto de los servicios. Si se especifica, se utiliza la interfaz de punto final de servicio para determinar el contrato WSDL abstracto. (String)

portName="" -> wsdl:portName. El valor por omisión es WebService.name más Port. (String)

wsdlLocation="" -> Especifica la dirección Web del documento WSDL que define el servicio Web. La dirección Web puede ser relativa o absoluta. (String)

- @WebMethod indica un método que es una operación de servicio Web. Destino de anotación: Method. Parámetros que permite:

operationName="" -> Especifica el nombre de wsdl:operation que coincide con este método. El valor por omisión es el nombre del método Java. (String)

action="" -> Define la acción de esta operación. En los enlaces SOAP, este valor determina el valor de la cabecera SOAPAction. El valor por omisión es el nombre del método Java. (String)

exclude="" -> Especifica si se ha de excluir un método del servicio Web. El valor por omisión es false.(Boolean)

- @Oneway indica un método como una operación unidireccional de servicio Web que sólo tiene un mensaje de entrada y ningún mensaje de salida. Destino de anotación: Method. No hay parámetros.

- @WebParam personaliza la correlación de un parámetro individual con una parte de mensaje de servicio Web y un elemento XML. Destino de anotación: Parameter. Parámetros que permite:

name="" -> El nombre del parámetro. Si la operación es una RPC (Remote Procedure Call) y no se especifica el atributo partName, este es el nombre del atributo wsdl:part que representa el parámetro. Si la operación es de estilo documento o si el parámetro se correlaciona con una cabecera, -name es el nombre local del elemento XML que representa el parámetro. Este atributo es necesario si la operación es de estilo documento, el estilo de parámetro es BARE, y la modalidad OUT o INOUT. (String)

partName="" -> Define el nombre del atributo wsdl:part que representa este parámetro. Sólo se utiliza si la operación es de estilo RPC o si el estilo de documento y el estilo de parámetro es BARE. (String)

targetNamespace="" -> Especifica el espacio de nombres XML del elemento XML del parámetro. Se aplica únicamente a los enlaces de documentos cuando el atributo se correlaciona con un elemento XML. El valor por omisión es el targetNamespace del servicio Web. (String)

mode="" -> El valor representa la dirección en que fluye el parámetro para este método. Los valores válidos son IN, INOUT y OUT. (String)

header="" -> Especifica si el parámetro es una cabecera de mensaje y no el cuerpo de un mensaje. El valor por omisión es false. (Boolean)

- @WebResult personaliza la correlación de un valor de retorno con una parte WSDL o elemento XML. Destino de anotación: Method. Parámetros que permite:

name="" -> Especifica el nombre del valor de retorno como figura en el archivo WSDL y aparece en los mensajes de la comunicación. Para los enlaces RPC, este es el nombre del atributo wsdl:part que representa el valor de retorno. Para los enlaces de documentos, el parámetro -name es el nombre local del elemento XML que representa el valor de retorno. El valor por omisión es return para enlaces RPC y DOCUMENT/WRAPPED. El valor por omisión es el nombre de método más Response para enlaces DOCUMENT/BARE. (String)

targetNamespace="" -> Especifica el espacio de nombres XML para el valor de retorno. Este parámetro sólo se utiliza si la operación es de estilo RPC o si la operación es de estilo DOCUMENT y el estilo de parámetro es BARE. (String)

header="" -> Especifica si el resultado se lleva a cabo en una cabecera. El valor por omisión es false. (Boolean)

partName="" -> Especifica el nombre de la parte para el resultado con las operaciones RPC o DOCUMENT/BARE. El valor por omisión es @WebResult.name. (String)

- @HandlerChain asocia el servicio Web con una cadena de manejadores definida externamente. Destino de anotación: Type. Parámetros que permite:

file="" -> Especifica la ubicación del archivo de la cadena de manejadores. La ubicación del archivo es un java.net.URL absoluto con forrmato externo o una vía de acceso relativa al archivo de clases. (String)

name="" -> Especifica el nombre de la cadena de manejadores en el archivo de configuración. (String)

- @SOAPBinding especifica la correlación del servicio Web en el protocolo de mensajes SOAP. Destino de anotación: Type o Method. Parámetros que permite:

style="" -> Define el estilo de codificación para los mensajes enviados a y desde el servicio Web. Los valores válidos son DOCUMENT y RPC. El valor por omisión es DOCUMENT. (String)

use="" -> Define el formato utilizado para los mensajes enviados a y desde el servicio Web. El valor por omisión es LITERAL. ENCODED no está soportado en Feature Pack for Web Services. (String)

parameterStyle="" -> Determina si los parámetros del método representan todo el cuerpo del mensaje o si los parámetros son elementos envueltos en un elemento de nivel superior con el nombre de la operación. Los valores válidos son WRAPPED o BARE. Sólo puede utilizar el valor BARE con los enlaces de estilo DOCUMENT. El valor por omisión es WRAPPED.(String)

Mas info en Web Services Metadata Annotations (JSR 181)

2 comentarios:

  1. Que tal, tengo una duda sobre este tema, sera que me puedas ayudar?
    Porque no se puede hacer inyección de un bean con @Autowired cuando se usa este plugin?

    ResponderEliminar
  2. Hola. Gracias por el excelente post. Disculpa una pregunta. ¿Cómo puedo hacer si necesito que el servicio en el WSDL me devuelva varios parámetros?. Muchas gracias.

    ResponderEliminar