JAX-RS / Wink integration components

Defines an API and default provides for using Juneau serializers and parsers as JAX-RS providers.

Table of Contents
  1. Juneau JAX-RS Provider

1 - Juneau JAX-RS Provider

The Juneau framework contains the org.apache.juneau.rest.jaxrs package for performing simple integration of Juneau serializers and parsers in JAX-RS compliant environments.

It should be noted that although some of the functionality of the Juneau Server API is provided through the JAX-RS integration components, it is not nearly as flexible as using the {@link org.apache.juneau.rest.RestServlet} class directly.

What you can do with the Juneau JAX-RS provider classes:

What you can't do with the Juneau JAX-RS provider classes:

Juneau JAX-RS Provider API

The Juneau JAX-RS provider API consists of the following classes:

For the most part, when using these components, you'll either use the existing DefaultProvider or JuneauProvider providers, or define your own by subclassing BaseProvider.

Example:

The juneau_sample.war project contains a sample HelloWorldResource class that shows how to use the JAX-RS provider. It uses Wink as the JAX-RS implementation.

Wink is configured by registering the following servlet in the web.xml file of the web app:

<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.3"> <servlet> <servlet-name>WinkService</servlet-name> <servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class> <init-param> <param-name>applicationConfigLocation</param-name> <param-value>/WEB-INF/wink.cfg</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>WinkService</servlet-name> <url-pattern>/wink/*</url-pattern> </servlet-mapping> </web-app>

The wink.cfg file lists our default provider and our sample resource:

org.apache.juneau.rest.jaxrs.DefaultProvider com.foo.sample.jaxrs.HelloWorldResource

Interestingly, the DefaultProvider itself is a subclass of BaseProvider with no code at all. It consists of annotations only:

@Provider @Produces( "application/json,text/json,"+ // JsonSerializer "application/json+schema,text/json+schema,"+ // JsonSchemaSerializer "text/xml,"+ // XmlDocSerializer "text/xml+schema,"+ // XmlDocSerializer "text/html,"+ // HtmlDocSerializer "application/x-www-form-urlencoded,"+ // UrlEncodingSerializer "text/xml+soap,"+ // SoapXmlSerializer "text/xml+rdf,"+ // RdfXmlDocSerializer "application/x-java-serialized-object" // JavaSerializedObjectSerializer ) @Consumes( "application/json,text/json,"+ // JsonParser "text/xml,"+ // XmlParser "text/html,"+ // HtmlParser "application/x-www-form-urlencoded" // UrlEncodingParser ) @JuneauProvider( serializers={ JsonSerializer.class, JsonSchemaSerializer.class, XmlDocSerializer.class, XmlSchemaDocSerializer.class, HtmlDocSerializer.class, UrlEncodingSerializer.class, SoapXmlSerializer.class, RdfXmlDocSerializer.class, JavaSerializedObjectSerializer.class }, parsers={ JsonParser.class, XmlParser.class, HtmlParser.class, UrlEncodingParser.class } ) public final class DefaultProvider extends BaseProvider {}

Similarly, if you're defining your own JAX-RS provider, you can do so using annotations only.

Our sample resource is shown below. In this example, we've specified a @RestMethod annotation on the getter to show how properties can be overridden on the serializers/parsers at the method level. This annotation is optional.

@Path("/helloworld") public class HelloWorldResource { // Our bean message class public static class Message { // No-arg bean constructor (needed for parsers) public Message() {} public Message(String text, String author) { this.text = text; this.author = author; } public String text; public String author; } private static Message message = new Message("Hello world", "John Smith"); @GET @Produces("*/*") @RestMethod( /* Override some properties */ properties={ @Property(name=SerializerContext.SERIALIZER_useWhitespace, value="true"), @Property(name=JsonSerializerContext.LAX_MODE, value="true") } ) public Message getMessage() { return message; } @PUT @Produces("*/*") @Consumes("*/*") public Message replaceMessage(Message message) { HelloWorldResource.message = message; return message; } }

When we start up the servlet, we can interact with the resource using cURL. In these examples, note that the SERIALIZER_useWhitespace and LAX_MODE settings cause the output to be readable instead of condensed.

C:\>curl.exe -H "Accept: text/json" -X GET http://localhost:9080/sample/wink/helloworld { text:"Hello world", author:"John Smith" }

C:\>curl.exe -H "Accept: text/html" -X GET http://localhost:9080/sample/wink/helloworld <html> <head> </head> <body> <table type="object"> <tr> <th> <string>key</string> </th> <th> <string>value</string> </th> </tr> <tr> <td> <string>text</string> </td> <td> <string>Hello world</string> </td> </tr> <tr> <td> <string>author</string> </td> <td> <string>John Smith</string> </td> </tr> </table> </body> </html>

C:\>curl.exe -H "Accept: text/xml" -X GET http://localhost:9080/sample/wink/helloworld <?xml version="1.0" encoding="UTF-8"?> <object> <text>Hello world</text> <author>John Smith</author> </object>

C:\>curl.exe -H "Accept: application/x-www-form-urlencoded" -X GET http://localhost:9080/sample/wink/helloworld text='Hello+world'&author='John+Smith'

C:\>curl.exe -H "Accept: text/xml+schema" -X GET http://localhost:9080/sample/wink/helloworld <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <xs:element name="object" nillable="true"> <xs:complexType> <xs:sequence minOccurs="0" maxOccurs="unbounded"> <xs:element name="text" type="xs:string" nillable="true" minOccurs="0"/> <xs:element name="author" type="xs:string" nillable="true" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="null"/> </xs:schema>

C:\>curl.exe -H "Accept: application/x-java-serialized-object" -X GET http://localhost:9080/sample/wink/helloworld detailMessaget ↕Ljava/lang/String;[ ption(Vx τå▬5☻ xr ↔java.io.ObjectStreamExceptiond├Σkì9√▀☻ xr ‼java.io.IOExcept stackTracet ▲[Ljava/lang/StackTraceElement;xpq t /org.apache.juneau.samples.jaxrs.HelloWorldResource$Messageur ▲[Ljava.lang.Sta lineNumberL ♫declaringClassq ~ ♠LfileNameq ~ ♠L methodNameq ~ ♠xp ♦át →java.io.ObjectOutputStreamt ↨ObjectOutputStream.javat ♀writeObject0sq ~ ♀ ☺[t →java.io.Obje 3org.apache.juneau.serializer.OutputStreamSerializert ←OutputStreamSerializer.javat serializesq ~ ♀ ^t &com.ib &t /org.apache.wink.server.handlers.AbstractHandlert ¶AbstractHandler.javat ♫handleResponsesq ~ ♀ →t 5org.apache. sq ~ ♀ Ct 5org.apache.wink.server.handlers.AbstractHandlersChaint →AbstractHandlersChain.javat doChainsq ~ ♀ 't ♠handlesq ~ ♀ ▬t 5org.apache.wink.server.handlers.ResponseHandlersChaint →ResponseHandlersChain.javat ♠handlesq ~ ♫handleResponsesq ~ ♀ →t 5org.apache.wink.server.handlers.ResponseHandlersChaint →ResponseHandlersChain.javat ♠ha tHandlersChain.javat doChainsq ~ ♀ Zt -org.apache.wink.server.internal.log.Responsest ♫Responses.javat ♫handleResp eHandlersChain.javat ♠handlesq ~ ♀ Ct 5org.apache.wink.server.handlers.AbstractHandlersChaint →AbstractHandlersCha handleRequestsq ~ ♀ |t 3org.apache.wink.server.internal.servlet.RestServlett ►RestServlet.javat servicesq ~ ♀ ☻£t handleRequestsq ~ ♀ ├t -com.ibm.ws.webcontainer.channel.WCChannelLinkt ↕WCChannelLink.javat ♣readysq ~ ♀ ☺─t 4com ►handleNewRequestsq ~ ♀ ☺1t 4com.ibm.ws.http.channel.inbound.impl.HttpInboundLinkt ¶HttpInboundLink.javat ♫process nnectionInitialReadCallback.javat ¶sendToDiscriminatorssq ~ ♀ qt <com.ibm.ws.tcp.channel.impl.NewConnectionInitial ┘t $com.ibm.io.async.AbstractAsyncFuturet ↑AbstractAsyncFuture.javat ♫invokeCallbacksq ~ ♀ ít #com.ibm.io.async. t ↕ResultHandler.javatcompletesq ~ ♀ ♥t ▲com.ibm.io.async.ResultHandlert ↕ResultHandler.javat ▬runEventProcessingLo on: java.io.NotSerializableException: org.apache.juneau.samples.jaxrs.HelloWorldResource$Message

The following shows the PUT method being invoked. In this case, we're passing in the new bean as a JSON object. Also notice how the response is in standard condensed JSON since we did not override any properties on the REST method.

C:\>curl.exe -H "Content-Type: text/json" -H "Accept: text/json" -d "{text:'Hello again',author:'Jane Doe'}" -X PUT http://localhost:9080/sample/wink/helloworld {"text":"Hello again","author":"Jane Doe"}