Wednesday, 26 August 2015

Jersey : Sub resources

Resource classes are able to partially process a request and provide another "sub" resource object that can process the remainder of the request.

Resource methods that have a @Path annotation, but no HTTP method are considered sub-resource locators.
For Example
@Path("employees")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class EmployeeResource {

 @Path("/{employeeId}/address")
 public AddressResource getAddress(){
  AddressResource resource = new AddressResource();
  System.out.println("Hello");
  return resource;
 }
}

public class AddressResource {

 @GET
 @Path("/temporaryAddress")
 public Address getTempAddress(@PathParam("employeeId") long empId) {
  return EmployeeService.getEmployee(empId).getTempAddrees();
 }

 @GET
 @Path("/permanentAddress")
 public Address getPermAddress(@PathParam("employeeId") long empId) {
  return EmployeeService.getEmployee(empId).getPermAddrees();
 }
}

In this code snippet, the getAddress method is the subresource locator that provides the AddressResource object, which services requests for temporaryAddress, permanentAddress.

If your HTTP request is /employees/1/address/permanentAddress. “/employees/1/address” returns AddressResource object, At runtime, JAX-RS sends a GET request to getPermAddress method.

If your HTTP request is /employees/1/address/temporaryAddress. “/employees/1/address” returns AddressResource object, At runtime, JAX-RS sends a GET request to getTempAddress method.

Till now we developed following REST APIs.
API URL
Method
Description
/employees
GET
Return all employees
/employees
POST
Add new employee
/employees/employeeID
GET
Get employee details for given id
/employees/employeeID
PUT
Update specific employee
/employees/employeeID
DELETE
Delete employee details for given id
/employees?city=Bangalore
GET
Get all employees staying at Bangalore
/employees?start=1&size=2
GET
Get all employees with ids 1, 2 and 3

Now we are going to develop two more APIs, which will give, permanent and temporary addresses.

/employees/1/address/temporaryAddress
Above API returns temporary address.

/employees/1/address/permanentAddress
Above API returns permanent address.

Following is the step-by-step procedure to build complete application.

Step 1: Create package “com.jersey_tutorial.model” to store all model classes.

Step 2:  Create model classes Employee, Address. 

Address.java
package com.jersey_tutorial.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Address {
 private String street;
 private String city;
 private String state;
 private String country;

 public Address() {
  this("No Data", "No Data", "No Data", "No Data");
 }

 public Address(String area, String city, String state, String country) {
  super();
  this.street = area;
  this.city = city;
  this.state = state;
  this.country = country;
 }

 public String getArea() {
  return street;
 }

 public String getCity() {
  return city;
 }

 public String getCountry() {
  return country;
 }

 public String getState() {
  return state;
 }

 public void setArea(String area) {
  this.street = area;
 }

 public void setCity(String city) {
  this.city = city;
 }

 public void setCountry(String country) {
  this.country = country;
 }

 public void setState(String state) {
  this.state = state;
 }

}


Employee.java
package com.jersey_tutorial.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Employee {
 private String firstName;
 private String lastName;
 private long id;
 private Address permAddrees;
 private Address tempAddrees;

 public Employee() {
  this("No Data", "No Data", -1, new Address(), new Address());
 }

 public Employee(String firstName, String lastName, long id,
   Address permAddrees, Address tempAddrees) {
  super();
  this.firstName = firstName;
  this.lastName = lastName;
  this.id = id;
  this.permAddrees = permAddrees;
  this.tempAddrees = tempAddrees;
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public long getId() {
  return id;
 }

 public void setId(long id) {
  this.id = id;
 }

 public Address getPermAddrees() {
  return permAddrees;
 }

 public void setPermAddrees(Address permAddrees) {
  this.permAddrees = permAddrees;
 }

 public Address getTempAddrees() {
  return tempAddrees;
 }

 public void setTempAddrees(Address tempAddrees) {
  this.tempAddrees = tempAddrees;
 }

}

XmlRootElement annotation is used to map a Java class to an XML element.

Step 3: Create a package com.jersey_tutorial.services


Step 4: Create EmployeeService class to get all Employee details.
package com.jersey_tutorial.services;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import com.jersey_tutorial.model.Address;
import com.jersey_tutorial.model.Employee;

public class EmployeeService {
 private static TreeMap<Long, Employee> employees = new TreeMap<>();

 static {
  initializeEmployees();
 }

 private static void initializeEmployees() {
  Address tempAddr1 = new Address("Electronic City", "Bangalore",
    "Karnataka", "India");
  Address tempAddr2 = new Address("BTM Layout", "Bangalore", "Karnataka",
    "India");
  Address tempAddr3 = new Address("SR Nagar", "Hyderabad",
    "Andhra Pradesh", "India");

  Address permAddr1 = new Address("Marthali", "Bangalore", "Karnataka",
    "India");
  Address permAddr2 = new Address("Bharath Nagar", "Hyderabad",
    "Andhra Pradesh", "India");
  Address permAddr3 = new Address("Bharath Nagar", "Hyderabad",
    "Andhra Pradesh", "India");

  Employee emp1 = new Employee("Hari Krishna", "Gurram", 1, permAddr1,
    tempAddr1);
  Employee emp2 = new Employee("PTR", "PTR", 2, permAddr2, tempAddr2);
  Employee emp3 = new Employee("Rama Krishna", "Gurram", 3, permAddr3,
    tempAddr3);

  employees.put(1l, emp1);
  employees.put(2l, emp2);
  employees.put(3l, emp3);
 }

 public static Map<Long, Employee> getAllEmployees() {
  return employees;
 }

 public static List<Employee> getEmployeesForCity(String city) {
  List<Employee> employeesForCity = new ArrayList<>();

  for (Employee emp : employees.values()) {
   if (emp.getPermAddrees().getCity().equals(city)
     || emp.getTempAddrees().getCity().equals(city)) {
    employeesForCity.add(emp);
   }
  }
  return employeesForCity;
 }

 public static List<Employee> getEmployeesPaginated(long start, long size) {
  return new ArrayList<>(employees
    .subMap(start, true, start + size, true).values());
 }

 public static Employee getEmployee(long id) {
  return employees.get(id);
 }

 public static Employee addEmployee(Employee emp) {
  long newId = employees.size() + 1;
  emp.setId(newId);
  employees.put(newId, emp);
  return emp;
 }

 public static Employee updateEmployee(long id, Employee emp) {
  emp.setId(id);
  employees.put(id, emp);
  return emp;
 }

 public static Employee deleteEmployee(long empId) {
  Employee emp = employees.get(empId);
  employees.remove(empId);
  return emp;
 }
}

Step 5: Create a package com.jersey_tutorial.resources.


Step 6: Create EmployeeResource class.
package com.jersey_tutorial.resources;

import java.util.ArrayList;
import java.util.List;

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.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import com.jersey_tutorial.model.Employee;
import com.jersey_tutorial.services.EmployeeService;

@Path("employees")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class EmployeeResource {

 @GET
 public List<Employee> getAllEmployees(@QueryParam("city") String city,
   @QueryParam("start") long start, @QueryParam("size") long size) {
  if (city != null)
   return EmployeeService.getEmployeesForCity(city);

  if (start > 0 && size > -1)
   return EmployeeService.getEmployeesPaginated(start, size);

  return new ArrayList<>(EmployeeService.getAllEmployees().values());
 }

 @GET
 @Path("/{employeeId}")
 public Employee getEmployee(@PathParam("employeeId") long empId) {
  return EmployeeService.getEmployee(empId);
 }

 @POST
 public Employee addEmployee(Employee emp) {
  return EmployeeService.addEmployee(emp);
 }

 @PUT
 @Path("/{employeeId}")
 public Employee updateEmployee(@PathParam("employeeId") long empId,
   Employee emp) {
  return EmployeeService.updateEmployee(empId, emp);
 }

 @DELETE
 @Path("/{employeeId}")
 public Employee removeEmployee(@PathParam("employeeId") long empId) {
  return EmployeeService.deleteEmployee(empId);
 }
 

 @Path("/{employeeId}/address")
 public AddressResource getAddress(){
  AddressResource resource = new AddressResource();
  System.out.println("Hello");
  return resource;
 }
}


Step 7: Create AddressResource class.
package com.jersey_tutorial.resources;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

import com.jersey_tutorial.model.Address;
import com.jersey_tutorial.services.EmployeeService;

public class AddressResource {

 @GET
 @Path("/temporaryAddress")
 public Address getTempAddress(@PathParam("employeeId") long empId) {
  return EmployeeService.getEmployee(empId).getTempAddrees();
 }

 @GET
 @Path("/permanentAddress")
 public Address getPermAddress(@PathParam("employeeId") long empId) {
  return EmployeeService.getEmployee(empId).getPermAddrees();
 }
}


Following is the web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 id="WebApp_ID" version="3.0">
 <display-name>jersey_tutorial</display-name>
 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
  <welcome-file>index.htm</welcome-file>
  <welcome-file>index.jsp</welcome-file>
  <welcome-file>default.html</welcome-file>
  <welcome-file>default.htm</welcome-file>
  <welcome-file>default.jsp</welcome-file>
 </welcome-file-list>

 <servlet>
  <servlet-name>Jersey REST Service</servlet-name>
  <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
  <init-param>
   <param-name>jersey.config.server.provider.packages</param-name>
   <param-value>com.jersey_tutorial.resources</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>Jersey REST Service</servlet-name>
  <url-pattern>/*</url-pattern>
 </servlet-mapping>
</web-app>


Following are the dependencies I used.
<dependencies>
 <dependency>
  <groupId>org.glassfish.jersey.containers</groupId>
  <artifactId>jersey-container-servlet-core</artifactId>
  <version>2.21</version>
 </dependency>

 <dependency>
  <groupId>org.glassfish.jersey.core</groupId>
  <artifactId>jersey-server</artifactId>
  <version>2.21</version>
 </dependency>

 <dependency>
  <groupId>org.glassfish.jersey.media</groupId>
  <artifactId>jersey-media-moxy</artifactId>
  <version>2.21</version>
 </dependency>

</dependencies>

Run the application on server.
Above URL gives you temporary address.

Above URL gives you permanent address.

Complete Project structure looks like below.






Prevoius                                                 Next                                                 Home

No comments:

Post a Comment