Pages

Sunday, 7 December 2014

Creating WADL friendly RESTFul Service using JDeveloper

Usecase:

This blog post talks about creating RESTful services from a java class in JDeveloper. The service is an Employee information service consisting of various operations involving GET, PUT, POST and DELETE verbs & parameters.

Pre-requisites:

JDeveloper 12.1.3.0.0

Steps:
  • Create a new custom application 'EmployeeService' in JDeveloper.
  • Createa a java class. Call it Employee.java. This class will be a bean holding the fields and getters and setters required for the employee.
  1. package project1;
    import javax.xml.bind.annotation.XmlRootElement;
    @XmlRootElement
    public class Employee {
        String name;
        int id;
       
        public Employee() {
            super();
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public int getId() {
            return id;
        }
    }

  • Create another java class called EmployeeWrapper.java. This is a wrapper class. The purpose of having the wrapper class is that it will ensure that a clean and complete WADL is generated at the end.
  1. package project1;
    import java.net.URI;
    import java.util.ArrayList;
    import java.util.List;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.bind.annotation.XmlElement;
    
    @XmlRootElement
    public class EmployeeList {
    
        private List<Employee> list = new ArrayList<Employee>();
    
    
        public EmployeeList() {
    
        }
    
        public EmployeeList(List<Employee> list) {
            super();
            this.list = list;
        }
    
     @XmlElement
        public List<Employee> getList() {
            return list;
        }
    }

  • Finally, we need another java class called the EmployeeService.java. This will be main service class in which we will configure the various operations of the service. You can copy the below code into your class and use the lightbulb next to @Path annotation to configure project for JAXRS service. Select the option JAXRS 2.0 style on being prompted. JDev will take care of the library configurations for you.
  1. package project1;
    import java.util.Iterator;
    import java.util.List;
    import java.util.concurrent.CopyOnWriteArrayList;
    import javax.ws.rs.Consumes;
    import javax.ws.rs.DELETE;
    import javax.ws.rs.GET;
    import javax.ws.rs.POST;
    import javax.ws.rs.PUT;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;
    import javax.ws.rs.QueryParam;
    
    @Path("project1")
    public class EmployeeService {
        private static List<Employee> employeeList = new CopyOnWriteArrayList<Employee>();
    
        public EmployeeService() {
            addEmp();
        }
    
        @GET
        @Produces("application/xml")
        public EmployeeList getEmpList() {       
            return new EmployeeList(employeeList);
        }
    
        @PUT
        @Consumes("application/xml")
        @Produces("application/xml")
        public EmployeeList addEmployee(Employee emp) {
            employeeList.add(emp);
            return new EmployeeList(employeeList);
        }
    
        @DELETE
        @Consumes("application/xml")
        @Produces("application/xml")
        public EmployeeList deleteEmployee(@QueryParam("name") String name) {
            employeeList.remove(getEmp(name));
            return new EmployeeList(employeeList);
        }
    
        @POST
        @Consumes("application/xml")
        @Produces("application/xml")
        public EmployeeList updateEmployee(@QueryParam("id") int id, @QueryParam("name") String name) {
            Employee emp1 = new Employee();
            emp1 = getEmpById(id);
            if(emp1 != null)
                emp1.setName(name);
            return new EmployeeList(employeeList);
        }
        
        public Employee getEmp(String name) {
            Iterator i = employeeList.iterator();
            while (i.hasNext()) {
                Employee e = (Employee)i.next();
                if (e.getName().equalsIgnoreCase(name))
                    return e;
            }
            return null;
        }
        
        public Employee getEmpById(int id) {
            Iterator i = employeeList.iterator();
            while (i.hasNext()) {
                Employee e = (Employee)i.next();
                if (e.getId() == id)
                    return e;
            }
            return null;
        }
    
        public void addEmp() {
            if (employeeList.isEmpty()) {
                Employee emp1 = new Employee();
                emp1.setId(1);
                emp1.setName("Arnold");
                employeeList.add(emp1);
                
                Employee emp2 = new Employee();
                emp2.setId(2);
                emp2.setName("Andy");
                employeeList.add(emp2);
            }
        }
    }
  • Run EmployeeService.java.
  • Click on the generated WADL URL. The Jdev internal tester - HTTP analyzer opens up. It shows you the WADL in a well defined manner with the various operations, input types, output types and parameters. It also provides a link to the XSD.

  • Click on Test button corresponding to the operation you want to invoke. HTTP analyzer window opens up in the REST Structure tab for you. As we have structured our service with wrapper classes, the REST structure renders data in a readable form. Below are snippets of the outputs obtained for GET and POST operations. To see the XML structure, you can navigate to the HTTP Content tab.



Using the approach of having a wrapper class while you are dealing with lists will ensure a good WADL structure. Also, it gets easier to test the service in analyzer as you are presented with a neat form for input, and structured data in the output. Give it a try!!