Tuesday, 1 March 2011

Developing RESTful Web Services from JDeveloper 11g (11.1.1.4)

Representational State Transfer (REST) describes any simple interface that transmits data over a standardized interface (such as HTTP) without an additional messaging layer, such as SOAP. In this example we use JDeveloper to create a basic JAX-RS Web Service from support provided within the code editor as no wizard support exists within JDeveloper 11g at this stage.

1. Download the ZIP of Jersey which contains all the JARS we need here.

zip of Jersey

2. Create a basic workspace with 2 empty projects one called "Client" and the other "Demo".

3. For the "Demo" project create a project library as shown below. Basically we want to include those JAR files we downloaded at step #1.



In short we want to include these JAR files
  • asm-3.1.jar
  • jersey-core-1.5.jar
  • jersey-server-1.5.jar

4. In the "Demo" project add a class called "HelloWorld". We just use the Java Class Wizard here as we will then use annotations to complete the class itself to make it a RESTful Web Service itself.

package pas.au.jdev.rs;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;

@Path ("/helloworld")
public class HelloWorld
{
  @Context 
  private UriInfo context;
  
  public HelloWorld()
  {
  }
  
  // Specifies that the method processes HTTP GET requests 
  @GET
  @Path("sayHello")
  @Produces("text/plain")
  public String sayHello() 
  {
     return "Hello World!";
  }
  
  // Specifies that the method processes HTTP GET requests
  @GET
  @Path("sayHelloWithName")
  @Produces("text/plain")
  public String sayHelloWithName(@QueryParam("name")String name) 
  {
     return String.format("Hello %s", name.toUpperCase());
  }  
}

5. At this point we have to create a web.xml to to expose the Jersey Servlet adapter or update an existing web.xml should one already exist in your project. JDeveloper does not automatically add the servlet class to the web.xml file. Instead, you are prompted to confirm whether you want to add it when you call a JAX-RS method from your code. For example:

@Path ("/helloworld")

When you place the cursor on this line of code above you will see the option to configure web.xml in the left hand gutter of the code editor.

Note: Why is the web.xml file not updated automatically? In the future, when you deploy to a Java EE 6.0 container, an update to the web.xml will not be required. Therefore, this is set up as an optional activity.

The web.xml would then look as follows.
<?xml version = '1.0' encoding = 'windows-1252'?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5" xmlns="http://java.sun.com/xml/ns/javaee">
  <servlet>
    <servlet-name>jersey</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>jersey</servlet-name>
    <url-pattern>/jersey/*</url-pattern>
  </servlet-mapping>
</web-app>

6. In the application navigator you will notice that your class now is known as a Web Service using the Web Service icon which JDeveloper has used for JAX-WS and JAX-RPC 1.4 Web Services. At this point we can run it to deploy it to the Integrated Server from JDeveloper by selecting the "Run" context menu of your RESTful Web Service.

7. If all goes well you should see at the bottom of the log window something as follows.

[09:32:34 PM] ----  Deployment finished.  ----
Run startup time: 5585 ms.
[Application JAX-RS-RESTFulWebServices deployed to Server Instance IntegratedWebLogicServer]


Target Application WADL -- http://localhost:7101/jaxrs-demo/jersey/application.wadl


Target URL -- http://localhost:7101/jaxrs-demo/jersey/helloworld/sayHello

8. At this point we can test the JAX-RS resource using a web browser, for example. Yes even though we are using plain text response that would still work. Enter the URL below into a browser and verify output as shown below.



Note: You could even click on the "target URL" from the log window if you want to use the "HTTP Analyzer" itself which would be another quick way to do this as shown below


9. Now we know it works we simply will invoke it from a client. To do this we edit the "Client" project properties and ensure we have added the 3 JAR files we obtained from step #1 above.


In short we want to include these JAR files
  • jersey-client-1.5.jar
  • jersey-core-1.5.jar
10. In the "Client" project add a test class as follows.
package pas.au.jdev.rs.client;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;

public class HelloWorldClient
{
  public HelloWorldClient()
  {
  }

  public static void main(String[] args)
  {
    Client c = Client.create();
    System.out.println("** Simple GET request .... **");
    WebResource resource = 
      c.resource("http://localhost:7101/jaxrs-demo/jersey/helloworld/sayHello");
    String response = resource.get(String.class);
    
    System.out.println(response);
    
    System.out.println("** Simple GET request with Query Param **");
    WebResource resource2 = 
      c.resource("http://localhost:7101/jaxrs-demo/jersey/helloworld/sayHelloWithName");
    String response2 = resource2.queryParam("name", "pas").get(String.class);
    
    System.out.println(response2);
    
  }
}

11. Run the class and verify it shows output as follows.


** Simple GET request .... **
Hello World!
** Simple GET request with Query Param **
Hello PAS


The JDeveloper workspace would look as follows

5 comments:

Steve Racanovic said...

Hi, You should have the following libraries:

For Server

- asm-3.1.jar
- jersey-core-1.5.jar
- jersey-server-1.5.jar

For Client:

- jersey-core-1.5.jar
- jersey-client-1.5.jar

Cheers,

Pas Apicella said...

yep thanks I was using the WAR file bundled with WLS 10.3.4

Anonymous said...

Hi, how should be the web.xml file ?
Can you explain how to update it ? Thanks for a response. YL

Pas Apicella said...

I have updated the main post to include what the web.xml would look like which JDeveloper generates for you using the wizard which appears in the line gutter of the Code Editor.

Anonymous said...

Very easy instructions to get started. Thanks a lot.