dinsdag 1 maart 2011

How to create a RESTful web service that returns objects

Technology: ADF11g
Developed in: JDeveloper 11.1.1.3.0
Used database schema: none


Summary

In this blog a solution is provided how to create a RESTful web service that returns objects. One web service will be created with 2 methods to return an Employee instance and a list of Employee instances.

This blog is part of a sequence of 3 blogs:
  • How to create a RESTful web service that returns objects
  • How to create a web service client
  • How to create web service based ADF pages

Step 1

Create a new generic application in JDeveloper:



Step 2

Download the 'zip of Jersey' of the page:

http://jersey.java.net/nonav/documentation/latest/chapter_deps.html

Step 3

Extract the zip and copy the following jar files to the new created application (in a lib folder):
  • Asm-3.1.jar
  • Jersey-core-1.5.jar
  • Jersey-server-1.5.jar
  • Jersey-json-1.5.jar

Step 4

Open the project properties of the project in the new application and add these jar files (not the JAX-WS Web Services library will be added automatically later on):



Step 5

Create an Employee class which represents one employee (of the HR schema). Create accessors for all class variables. A second constructor is added so an employee can be created and initialized in one call.

Add above the class name the annotation XmlRootElement of class javax.xml.bind.annotation.XmlRootElement.

package nl.hr.demo.dataObjects;



import java.util.Date;

import javax.xml.bind.annotation.XmlRootElement;



@XmlRootElement

public class Employee {

private int employeeId;

private String firstName;

private String lastName;

private String email;

private String phoneNumber;

private Date hireDate;

private String jobId;

private double salary;

private double commissionPct;

private int managerId;

private int departmentId;



public Employee() {

super();

}

public Employee(int employeeId, String firstName, String lastName, String email, String phoneNumber, Date hireDate, String jobId, double salary, double commissionPct, int managerId, int departmentId) {

super();

setEmployeeId(employeeId);

setFirstName(firstName);

setLastName(lastName);

setEmail(email);

setPhoneNumber(phoneNumber);

setHireDate(hireDate);

setJobId(jobId);

setSalary(salary);

setCommissionPct(commissionPct);

setManagerId(managerId);

setDepartmentId(departmentId);

}



// For all class variables create accessors

public void setXXX (XXX xxx) {

this.xxx = xxx;

}

public XXX getXXX () {

return xxx;

}

}


Step 6

Create the web service class that returns one or a list of employees. If a web service contains several (GET) methods each method should have its own path.

package nl.hr.demo.webservices;



import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.List;

import javax.ws.rs.GET;

import javax.ws.rs.Path;

import javax.ws.rs.Produces;

import javax.ws.rs.QueryParam;

import nl.hr.demo.dataObjects.Employee;



@Path("EmployeesService")

public class EmployeesServices {

public EmployeesServices() {

super();

}



@GET

@Path("getEmployeeById")

@Produces("application/json")

public Employee getEmployeeById(@QueryParam("id")int id) {

SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");

try {

if (id == 100) {

return new Employee(id, "Steven", "King", "SKING", "515.123.4567", sdf.parse("17-06-1987"), "AD_PRES", 24000, -1, -1, 90);

} else if (id == 101) {

return new Employee(id, "Neena", "Kochhar", "NKOCHHAR", "515.123.4568", sdf.parse("21-09-1989"), "AD_VP", 17000, -1, 100, 90);

}

return new Employee(id, "Lex", "De Haan", "LDEHAAN", "515.123.4569", sdf.parse("13-01-1993"), "AD_VP", 17000, -1, 100, 90);

} catch (Exception e) {

return null;

}

}



@GET

@Path("getAllEmployees")

@Produces("application/json")

public List<Employee> getAllEmployees() {

List<Employee> result = new ArrayList<Employee> ();

SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");

try {

result.add(new Employee(100, "Steven", "King", "SKING", "515.123.4567", sdf.parse("17-06-1987"), "AD_PRES", 24000, -1, -1, 90));

result.add(new Employee(101, "Neena", "Kochhar", "NKOCHHAR", "515.123.4568", sdf.parse("21-09-1989"), "AD_VP", 17000, -1, 100, 90));

result.add(new Employee(102, "Lex", "De Haan", "LDEHAAN", "515.123.4569", sdf.parse("13-01-1993"), "AD_VP", 17000, -1, 100, 90));

} catch (Exception e) {

return new ArrayList<Employee> ();

}

return result;

}

}

For this blog the result of the web service is hard coded.

The @Path annotation above the class definition contains a warning:



If you click on this warning a jersey servlet is added to the web.xml:

<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>


Step 7

Now the EmployeeService can be created so it can be deployed.

Right click in the Application Navigator on the EmployeeService java class and choose Create Web Service:
  • Give the web service a name for example EmployeeWebService
  • Choose SOAP 1.1 Binding
  • Leave all other options to their default value
Between the @Path annotation and the class definition a new line is added:

@WebService(name = "EmployeesWeb", serviceName = "EmployeesWebService", portName = "EmployeesWebPort")

And in the web.xml is added:

<servlet>

<servlet-name>EmployeesWebPort</servlet-name>

<servlet-class>nl.hr.demo.webservices.EmployeesServices</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>EmployeesWebPort</servlet-name>

<url-pattern>/EmployeesWebPort</url-pattern>

</servlet-mapping>


Step 8

Deploy the application as a EAR file to the weblogic server:



If you click on the Service and go to the testing tab you can test the webservice:



If we test getEmployeeById and query id 101 we get:



With result:



And test getAllEmployees results in:

1 opmerking: