Showing posts with label jax-rs. Show all posts
Showing posts with label jax-rs. Show all posts

1 September 2018

RD EE6 Web Services module 21 lab using JAX-RS 2

Create a JAX-RS 2 REST client application for your createAuthor and findAuthorById service.

  1. Make a REST client prject
    1. Make a new rsClient java application project  in Netbeans
    2. Make sure your Author webservice server project is open as well
    3. Add a new webservice client to the client project (File > new > Webservices > RESTful Java client)
      1. Select the REST resource, browse for your server project and select the Author REST service 
      2. Finish
        1. This creates you a project with the JAX-RS libraries and client sample code.
          1. You can use the sample code for your inspiration, but write your own client code
    4. Copy the domain classes of your server project + the JAXB adapters to the client project
  2. Call the createAuthor service
    1. In the main method of your client project create a javax.ws.rs.client.Client object
    2. Create a request that expects an XML or JSON reply
    3. Create a new Author object, without an id
    4. POST the author object in the body as a XML or JSON Entity. Example of the creation of a JSON entity: javax.ws.rs.client.Entity.json(author)
  3. Call the findAuthorById service to retrieve the Author you just created from the server
    1. If the createAuthor service is well written, the Location header in the javax.ws.rs.core.Response should contain the URL of the newly created Author (including the generated author id). Retrieve the URL from the Location header in the Response.
    2. Use the URL to retrieve the author, converted by the Client to an Author object
    3. Print the Author object to the console

JAX-RS 2.0 client example: Client class

public class MyClient {
  public static void main(String[] args) {
    System.out.println("What's the name of this author?: ");
    String authorId = new Scanner(System.in).next();
    
    Client client = ClientBuilder.newClient();
    WebTarget resource = client.target("http://localhost:8080/myrest/webresources");
    Response response = resource
            .path("author")
            .path(authorId)
            .request(MediaType.APPLICATION_JSON)
            .get();

     // historically getStatus returns an int, not a Response.Status
    if (response.getStatus() == Response.Status.OK.getStatusCode()) {
      Author author = response.readEntity(Author.class);
      System.out.println("Found author: " + author.getFirstName() + " " + author.getLastName());
    }else{
      String body = response.readEntity(String.class);
      System.out.println("Not correct (" + response.getStatusInfo().getReasonPhrase() + ")\n " +body);
    }
  }
}

22 February 2014

Jersey 1 filter classes

Classes in brown are also part of JAX-RS 2.


28 March 2013

JAX-RS 2.0 preview (updated)

Here's an overview of the most important new features in JAX-RS 2.0 (JSR339).
The JSR is currently in public review, so this is subject to change.

  • Asynchronous REST web services
  • REST web services are based on servlets. So the new asynchronous REST support looks a lot like the new asynchronous servlet support.
    The response to an asynchronous web service can be delegated to another thread.
     The webservice needs to pass the asynchronous response, to allow it to send a response.

    @Path ("/rest2/async")
    public class NoWaiter{
      @Asynchronous
      @GET 
      public String delegate(@Suspended AsyncResponse ctx) {
        // put context on a queue
        // for job to be picked up by a thread
        bloq.add(ctx);
        // exit immediatly
      }
    }
    
    class Handler implements Runnable{
      public void run(){
        AsyncResponse ctx bloq.take();
        // return response
        ctx.resume("response");
      }
    } 
  • Client API
  • Similar to Jersey 1 client API (some names change)
    Client client = ClientFactory.newClient();
    String result = client.target(“http://reasonsto.be”)
      .request("text/plain")
      .get(String.class); 
    
    Chaining async() in the call, the client becomes asynchronous:
    Future<String> result = client.target(“http://reasonsto.be”)
      .request("text/plain")
      .async()
      .get(String.class);
    You can also pass a listener to the asynchronous client:
    Future<String> result = client.target(“http://reasonsto.be”)
      .request("text/plain")
      .async()
      .get(new Hark()); 
    
    class Hark implements InvocationCallback<String>
    {
    public void completed(String result) {…}
    public void failed(InvocationException err) {…}
    }
  • Filters and Entity Interceptors
    • Similar to Jersey 1 filters 
    • @Provider annotated 
    • set order using @Priority
    • Filters wrap around an entire HTTP request. Mostly deal with HTTP headers, URI, method...
      • interface ContainerResponsFilter (javax.ws.rs.container)
        • void filter(ContainerResponseContext ctx) throws IOException
      • interface ContainerRequestFilter
        • void filter(ContainerRequestContext ctx) throws IOException 
        • Can have an additional @PreMatching annotation to run before JAX-RS resource method is selected (default is after resource method selection)
      • Throwing an exception will veto further processing of the message
      • javax.ws.rs.client contains similar clientside filters. Just replace Container with Client in the above interfaces. 
        • not annotated, but ClientBuilder, Client, and WebTarget all implement the Configurable interface. You can add your filter using its register(yourFilter) method.
    • Entity Interceptors wrap around the HTTP body <=> java Object marshalling/unmarshalling (e.g. for supporting compression encoding)
      •  interface WriterInterceptor
        • void aroundWriteTo(WriterInterceptorContext ctx) throws IOException, WebApplicationException
      • interface ReaderInterceptor
        • Object aroundReadFrom(ReaderInterceptorContext ctx) throws IOException, WebApplicationException
      • The aroundXXX  method naming indicate that these work like servlet filters:
        1. do some stuff
        2. ctx.proceed(): delegate to the next interceptor in the chain (of there is one)
        3. do some more stuff
    • Binding
      • Global
        •  @Provider
      • Local 
        • Using DynamicFeature
        • Using @NameBinding
          • Indicate that the usage of this resourcemethod is to be logged, using our own annotation:
          • @LogMe
            @GET
            @Produces("text/html")
            public String getXml(){ 
              return "<html>...</html>"
            }
            
          • Define the annotation
          • @NameBinding
            public @interface Logme{}
            
          • Implement the annotation
          • @LogMe
            public class LoggerLoggingFilter 
              implements ContainerRequestFilter, ContainerResponseFilter {
            // your logging code 
            }
            
        • Dynamic
          1. The filter is bound using one of the above methods, but there is an extra check to see if the filter should be applied
          2. The filter must implement the DynamicBinding interface
          3. The filter is applied only if the isBound() method returns true 
    • JSR303 validation
    • @Produces allows server to specify a mime type preference, using the qs attribute
    • Form class can be used as a resource method argument to capture a map of query parameters (shorthand for UriInfo.getQueryParameters()).