Module CSC5002—ASR6: Middleware and software architecture for distributed applications

Portail informatique

REST

REST, understand the skier example

For this lab, we use the Json and xml representations (the marshalling and unmarshalling are done with the Jakarta library), and the writing of REST services in Java with the JAX-RS specifications is achieved with the glassfish Jersey library.

Study the JAXRS examples

Understand and test all the JAX-RS examples (they are in the ExemplesREST/REST-JAXREST-01 directory of the csc-mw-examples project). Read the source files in your favorite development environment (e.g. Eclipse).

With the help of the README.md file, test the server:

  • With the Junit tests
  • With some get commands in the navigator
  • With get and posts commands via Postman
  • With java clients

When you have understood the examples (especially the one with the skiers), you are ready to write your own RESTFul client and server.

Verify first that you are able to answer the following questions

  • You do need to start the server, before starting any client. How do you start the server ?
    mvn exec:java@server
    You first have to compile the code with
    mvn clean install
  • On which TCP port is listening the server ? The TCP port is defined when you start the server. In our example the server reads in the file src/main/resources/rest.properties the address and the TCP port of the server
    rest.serveraddress=localhost:8083
    Then it defines its baseURI (http://localhost:8083/MyServer/) and creates the REST server that will be listening for requests.
    baseURI = "http://" + properties.getProperty("rest.serveraddress") + "/MyServer/"; GrizzlyHttpServerFactory.createHttpServer(URI.create(baseURI), rc)
  • What does that mean if I have the "Address already in use" error when I start the server ? It means that another process is already listening to this port, to find out which process is using this port you can use the following command
    lsof -i:8083
    If the answer is not empty, it gives you the details of the process listening on that port. If necessary, you can stop it with
    kill -9 {PID}
    (PID is the process number you have found with lsof). You can also use lsof to verify that your server is running.
  • What is the URL you can use in the navigator to see the server interface ?
    http://localhost:8083/MyServer/application.wadl
    It will show this kind of information. In this picture we have unfolded only the skiers resource. It gives a synthesis of the skiers resource API.
  • In which java class the skiers API is defined? package server, class SkiersRest
  • In which class the java server class is defined? package server, class Main
  • How do you specify the resources that will be handled by the Grizzly HTTP server? With the following line of code, you define the name of the packages that contain the REST resources.
    final ResourceConfig rc = new ResourceConfig().packages("server");
    In this package all the resources that have a @Path annotation are REST resources handled by the Grizzly HTTP server.
  • How the marshalling in json or in XML is realized? The marshalling is handled automatically according to the return class and the format provided by the resource and required by the client. In the following example:
    @GET @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Path("/searchByName") public Skier searchName(@QueryParam("name") final String name) throws JAXBException, IOException { Skier skier; getSkiersFromFile(fileName); skier = skiers.lookupName(name); if (skier == null) { throw new WebApplicationException(Response.Status.NOT_FOUND); } else { return skier; } }
    The return is of type Skier. The format provided by the method are XML and JSON. If the client requires JSON, the jersey and json libraries will manage the marshalling in JSON, if the client requires XML, the jersey and JAXB library will manage the marshalling in XML. In JAXB some annotations are necessary in the return class (Skier) to manage correctly the marshalling.
    NB: The client needs also a Skier class. This class may be generated based on an XML document or a Json String.
  • Use the logging facility to trace the interactions between the client and the server. For this purpose, provide a configuration file for the logging library through a java variable.
    mvn exec:java@client-skier -Djava.util.logging.config.file=src/main/resources/logging.properties
    This option may be very usefull for debugging your REST clients in the future labs. Here is an exerpt of the output with logging.
    PRÉCIS [sun.net.www.protocol.http.HttpURLConnection] sun.net.www.MessageHeader@1739b9c97 pairs: {PUT /MyServer/skiers/addvictory/Killy HTTP/1.1: null}{Content-Type: text/plain}{User-Agent: Jersey/3.0.8 (HttpUrlConnection 17.0.3)}{Host: localhost:8083}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Connection: keep-alive}{Content-Length: 8} PRÉCIS [sun.net.www.protocol.http.HttpURLConnection] sun.net.www.MessageHeader@27b21b711 pairs: {null: HTTP/1.1 204 No Content} PRÉCIS [sun.net.www.protocol.http.HttpURLConnection] sun.net.www.MessageHeader@7fa535375 pairs: {GET /MyServer/skiers/all HTTP/1.1: null}{Accept: text/xml}{User-Agent: Jersey/3.0.8 (HttpUrlConnection 17.0.3)}{Host: localhost:8083}{Connection: keep-alive} PRÉCIS [sun.net.www.protocol.http.HttpURLConnection] sun.net.www.MessageHeader@25d50bfd3 pairs: {null: HTTP/1.1 200 OK}{Content-Type: text/xml}{Content-Length: 358} PRÉCIS [org.glassfish.jersey.message.internal.ReaderInterceptorExecutor] Message body reader (class org.glassfish.jersey.jaxb.internal.XmlRootElementJaxbProvider$Text) is trying to close the entity input stream. Not closing. PRÉCIS [sun.net.www.protocol.http.HttpURLConnection] sun.net.www.MessageHeader@2cf7defc5 pairs: {GET /MyServer/skiers/searchByName?name=Killo HTTP/1.1: null}{Accept: application/xml}{User-Agent: Jersey/3.0.8 (HttpUrlConnection 17.0.3)}{Host: localhost:8083}{Connection: keep-alive} PRÉCIS [sun.net.www.protocol.http.HttpURLConnection] sun.net.www.MessageHeader@534df2fc2 pairs: {null: HTTP/1.1 404 Not Found}{Content-Length: 0} jakarta.ws.rs.NotFoundException: HTTP 404 Not Found
Congratulations, you are now ready to build your own REST application in Java !

 

 

 


$Date: 2020-10-06 00:31:01 +0200 (mar. 06 oct. 2020) $