CS639 Jersey Client Code for the firstREST service

==========================Test.java: Simple cases (no JAXB yet)=======================

This is the send-from String, receive-to String pattern, simple but not powerful....

package cs639.first.client;

import …

public class Test {

     public static void main(String[] args) {

          // This is using the Jersey client library, not part of JAX-RS

          // but supplied by the Jersey project to provide a more complete solution

          ClientConfig config = new DefaultClientConfig();

          Client client = Client.create(config);

          WebResource service = client.resource(getBaseURI());

          // Fluent interfaces

          System.out.println(service.path("rest").path("hello").accept(    ßsee expansion below

                    MediaType.TEXT_PLAIN).get(ClientResponse.class).toString());

          // Get plain text

          System.out.println(service.path("rest").path("hello").accept(

                    MediaType.TEXT_PLAIN).get(String.class));

          // Get XML

          System.out.println(service.path("rest").path("hello").accept(

                    MediaType.TEXT_XML).get(String.class));

          // Get HTML

          System.out.println(service.path("rest").path("hello").accept(

                    MediaType.TEXT_HTML).get(String.class));

          // Get JSON

          System.out.println(service.path("rest").path("hello").accept(

                    MediaType.APPLICATION_JSON).get(String.class));

         

          // Post XML, print echo: .type specifies the Content-Type of the posted message

          System.out.println(service.path("rest").path("hello").type(MediaType.TEXT_XML).accept(

                    MediaType.TEXT_XML).post(String.class, "<?xml version=\"1.0\"?><foo/>"));

          // same thing in smaller steps--

          WebResource postHelper = service.path("rest").path("hello");  //specify path

          Builder postHelper1 = postHelper.type(MediaType.TEXT_XML);  // spec. Content-Type header

          Builder postHelper2 = postHelper1.accept(MediaType.TEXT_XML);  // spec. Accept header

          String response = postHelper2.post(String.class, "<?xml version=\"1.0\"?><foo/>"); // do the POST

          System.out.println(response);

     }

 

     private static URI getBaseURI() {

          System.out.println("Getting base URI from env var TOMCAT_URL...");

          String tomcat = System.getenv("TOMCAT_URL");

          URI baseURI = UriBuilder.fromUri(tomcat + "/firstRest").build();

          System.out.println("...OK, found: " + tomcat);

          return baseURI;

     }

}

Analyzing a method chain:  Many methods return “this”, or a closely related object. See Wikipedia article on method chaining

 

From line marked ß above:   

service: a WebResource with already set URI http://localhost:8080/firstRest, say

service.path(“rest”): a WebResource with URI http://localhost:8080/firstRest/rest

service.path("rest").path("hello”): a WebResource with URI http://localhost:8080/firstRest/rest/hello

service.path("rest").path("hello").accept(MediaType.TEXT_PLAIN):  a WebResource.Builder with URI… and will send accept header as spec’d

service.path("rest").path("hello").accept(MediaType.TEXT_PLAIN).get(ClientResponse.class): invoke GET and return a ClientResponse object

 

Note: if we import com.sun.jersey.api.client.WebResource.Builder, we can call a WebResource.Builder simply a “Builder”. Builder is a public nested class of WebResource.

 

 

 

 

===========================Test2.java: More Advanced Cases======================

This shows how Jersey can send from DOM, receive into DOM,

--or send  from POJO, receive to POJO  (with help from JAXB),

--or mix of these. Also one example with StAX (not shown on handout)

package cs639.first.client;

// More advanced examples of Jersey client code

// Jersey can serialize/parse-to DOM, POJOs

// Also, StAX can produce XML in a String that Jersey can use

// Shows two ways: receive content object directly (naked case)

// or receive ClientResponse object that can deliver content object

// and related information such as the HTTP status (wrapped case)

// Note: these examples all work with POST because it both

// sends and receives XML, but the ideas can be used for

// any HTTP verb.

import ...;

 

public class Test2 {

     public static void main(String[] args) {

          // This is using the Jersey client library, not part of JAX-RS

          // but supplied by the Jersey project to provide a more complete

          // solution

          ClientConfig config = new DefaultClientConfig();

          Client client = Client.create(config);

          WebResource service = client.resource(getBaseURI());

 

          sendDOMReceiveDOM(service);

          sendPOJOReceiveDOM(service);  // see online

          sendPOJOReceivePOJO(service);

          sendStAXReceiveDOM(service);  // see online

     }

 

     // DOM out, DOM in--the Jersey client library knows DOM

     // serialization

     // just like the server-side Jersey support does

     private static void sendDOMReceiveDOM(WebResource service) {

 

          // Do it naked--just get contents back

          Document doc = buildSVGDOM();  // as in SimpleSVG.java

          Document responseDoc = service.path("rest").path("hello")

                    .type(MediaType.TEXT_XML).accept(MediaType.TEXT_XML)

                    .post(Document.class, doc);

          System.out.print("sendDOMReceiveDOM: ");

          checkSVGDOM(responseDoc);  // as in SimpleSVG.java

 

          // Do it wrapped--can get more info on response (status, headers,

          // etc.)

          ClientResponse response = service.path("rest").path("hello")

                    .type(MediaType.TEXT_XML).accept(MediaType.TEXT_XML)

                    .post(ClientResponse.class, doc);

          Document responseDoc1 = null;

          int status = response.getStatus();

 

          // Note: these constants are defined in HttpServletResponse

          if (status == 200) {

               responseDoc1 = response.getEntity(Document.class);

          } else if (status == 500) {

               // better to define own Exception class, throw...

               System.out.println("sendReceiveDOM: Service failure (HTTP 500)");

          } // else ...

          System.out.print("sendDOMReceiveDOM (wrapped case): ");

          checkSVGDOM(responseDoc1);

//(THE FOLLOWING WAS ADDED FOR HANDOUT)

             // Do it wrapped, then pull out response as String to see XML text

              response = service.path("rest").path("hello").type(MediaType.TEXT_XML)

                           .accept(MediaType.TEXT_XML).post(ClientResponse.class, doc);

              status = response.getStatus();

              // get Entity as String to see XML text

              if (status == 200) {

                     System.out.println("sendDOMReceiveString: "

                                  + response.getEntity(String.class));

              } else if (status == 500) {

                     System.out.println("sendDOMReceiveString: Service failure (HTTP 500)");

              }

       }

 

     // This uses the Todo POJO, and also an Echo POJO that has a Todo

     // POJO as a field, to handle the <echo>...</echo> response.

     private static void sendPOJOReceivePOJO(WebResource service) {

          Todo todo = new Todo("2", "get this working now!");

          // Do it naked--just get the content object

          Echo responsePOJO = service.path("rest").path("hello")

                    .type(MediaType.TEXT_XML).accept(MediaType.TEXT_XML)

                    .post(Echo.class, todo);

          System.out.println("sendPOJOReceivePOJO: contents of Echo POJO = "

                    + responsePOJO.getEcho().getSummary());

          // Do it wrapped--can get more info on response (status, headers,...)

          ClientResponse response = service.path("rest").path("hello")

                    .type(MediaType.TEXT_XML).accept(MediaType.TEXT_XML)

                    .post(ClientResponse.class, todo);

          Echo responsePOJO1 = null;

          int status = response.getStatus();

          // Note: these constants are defined in HttpServletResponse

          if (status == 200) {

               responsePOJO1 = response.getEntity(Echo.class);

              

          } else if (status == 500) {

               // better to define own Exception class, throw...

               System.out.println("sendPOJOReceivePOJO: Service failure (HTTP 500)");

          } // else ...

          System.out.println("sendPOJOReceivePOJO (wrapped case): contents of Echo POJO = "

                    + responsePOJO1.getEcho().getSummary());

}

         

 

 

=====================================Todo POJO=================================================

No XMLRootElement annotation, so can be used to serialize POJO-to-XML, but doesn’t show up as a possible root element for XML-to-POJO deserialization. Note that the sent message here has a todo element as its root element, but the return message has an echo element at the top

 

public class Todo {

       private String id;

       private String summary;

       private String description;

      

       public Todo(){

             

       }

       public Todo (String id, String summary){

              this.id = id;

              this.summary = summary;

       }

       public String getId() {

              return id;

       }

       public void setId(String id) {

              this.id = id;

       }

       public String getSummary() {

              return summary;

       }

       public void setSummary(String summary) {

              this.summary = summary;

       }

       public String getDescription() {

              return description;

       }

       public void setDescription(String description) {

              this.description = description;

       }     

}

===================================Echo POJO=====================================================

Has needed XMLRootElement annotation to be found  by JAXB when deserializing from XML. On the server side, Jersey sees web.xml <init-param> pointing to this package and passes that info to JAXB for scan of annotations, leading it to notice this class. On client side, looks at client objects.

 

package cs639.first.client;

 

import javax.xml.bind.annotation.XmlAccessType;

import javax.xml.bind.annotation.XmlAccessorType;

import javax.xml.bind.annotation.XmlRootElement;

 

@XmlAccessorType(XmlAccessType.FIELD)

@XmlRootElement(name = "echo")

public class Echo {

       private Todo todo;

 

       public Todo getEcho() {

              return todo;

       }

 

       public void setEcho(Todo todo) {

              this.todo = todo;

       }

}

=================================== Output from Test2 client (parts shown above)=================

Getting base URI from env var TOMCAT_URL...

...OK, found: http://localhost:8080

sendDOMReceiveDOM: checkSVGDOM: contents of desc: An example from Processing XML with Java

sendDOMReceiveDOM (wrapped case): checkSVGDOM: contents of desc: An example from Processing XML with Java

sendDOMReceiveString: <?xml version="1.0" encoding="UTF-8" standalone="no"?><echo><svg xmlns="http://www.w3.org/2000/svg"><desc>An example from Processing XML with Java</desc></svg></echo>

 

sendPOJOReceivePOJO: contents of Echo POJO = get this working now!

sendPOJOReceivePOJO (wrapped case): contents of Echo POJO = get this working now!