Web Services with Groovy and JAX-WS
The dynamic scripting language Groovy offers a strong integration into the Java platform. Therefore, you can use Java libraries and servers in your Groovy scripts. This article describes, how you can implement JAX-WS Web services by using Groovy. There is no further software needed except the Groovy installation and Java version 6 or higher.
The script presented in this article implements a service, which offers an operation for the creation of books. As parameter the operation receives a JavaBean of type Book. Listing 1 shows the service class.
@WebService (targetNamespace="http://predic8.com/groovy-jax/") @SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.BARE) class BookService{ @WebMethod public void add(Book book){ println "Name of the book: ${book.name}" } }
The BookService class uses the JWS @WebService annotation to identify itself as a Service Implemention Bean. If the class is used without the package declaration in the Defaultnamespace, the targetNamespace have to be indicated. You have to include the @WebMethod annotation, because in the other case every public method would be offered as an operation to the service class, like for example the public invokeMethod which BookService has inherited from GroovyObject. Thus only the marked methods are published. The JAX-WS implementation contained in Java version 6+ needs portable artifacts for the data types used in the Web Service interfaces. These portable artifacts can be generated from the annotated classes by using the tool wsgen. Anyhow, in our example we decided to work with the parameter Style BARE, which abstains from wrapper beans. Therefore we don't need wsgen and also no buildskript in our example. By using the parameter style BARE every operation maximally has one parameter. This parameter must be a bean. If you use Apache CXF instead of JAX-WS you don't have to care about portable artifacts, CXF doesn't need them. Everything CXF needs for an arbitrary signature of an operation created on the fly. Listing 2 shows the code of the GroovyBean Book
@XmlAccessorType(XmlAccessType.FIELD) class Book { String name String author }
The JAXB Annotation @XmlAcessorType(XmlAccessType.FIELD) is important.
By using the @XmlAccessorTyp annotation JAX-WS is induced to use the fields instead of the properties for the serialization of the bean. Without this annotation an error would appear when you start the web service. In Groovy each class inherits from GroovyObject. GroovyObject possesses a property named metaClass, which cannot be serialized. By using the AccessType Field the serialization is confined to name and author in our example. Now the service can be started. To start the service even without a web application and a web server we use the static method publish offered by the Endpoint class. Of course, a small standalone server is started in the background, which is included in the Java SDK.
Endpoint.publish("http://localhost:9000/book", new BookService())
Conclusion
As you can see in listing 4, it is easy to build a web service on the basis of some Groovy code. If you work with Apache CXF instead of JAX-WS by including the CXF libraries in the classpath, you don't have to deal with the restriction to the BARE Style. Now, you can start scripting web services!
import javax.jws.soap.* import javax.jws.* import javax.xml.ws.* import javax.xml.bind.annotation.* @XmlAccessorType(XmlAccessType.FIELD) class Book { String name String author } @WebService (targetNamespace="http://predic8.com/groovy-jax/") @SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.BARE) class BookService{ @WebMethod public void add(Book book){ println "Name of the book: ${book.name}" } } Endpoint.publish("http://localhost:9000/book", new BookService())