Wednesday, 26 August 2015

Jersey: Setting status codes and Headers

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
/employees/1/address/permanentAddress
GET
Get Permanent address of employee 1.
/employees/1/address/temporaryAddress
GET
Get Temporary address of employee 1.

In this post, I am going to explain How to send status codes and location headers.

By using Response class, we can set status codes and response headers.

In current design, whenever new employee is created status code 200 is returned by default.
But I want to return status code 201, whenever new employee created and add url for newly created employee in response headers.


Just update addEmployee method like below.
@POST
public Response addEmployee(Employee emp, @Context UriInfo uriInfo) {
  Employee employee = EmployeeService.addEmployee(emp);
  String empId = String.valueOf(employee.getId());
  URI uri = uriInfo.getAbsolutePathBuilder().path(empId).build();

  return Response.status(Status.CREATED).entity(employee).header("new_url", uri.toString()).build();
}

Response.status(Status.CREATED).entity(employee).header("new_url", uri.toString()).build();
Above statement set status code to 201, set response entity in the builder, and add an arbitrary header.

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.net.URI;
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.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;

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 Response addEmployee(Employee emp, @Context UriInfo uriInfo) {
    Employee employee = EmployeeService.addEmployee(emp);
    String empId = String.valueOf(employee.getId());
    URI uri = uriInfo.getAbsolutePathBuilder().path(empId).build();

    return Response.status(Status.CREATED).entity(employee)
        .header("new_url", uri.toString()).build();
  }

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

Complete Project structure looks like below.

When you try to add new employee using following url

and post data.
{
    "firstName": "Rama Krishna",
    "lastName": "Gurram",
    "permAddrees": {
        "area": "HSR Layout",
        "city": "Bangalore",
        "country": "India",
        "state": "Karnataka"
    },
    "tempAddrees": {
        "area": "auto nagae",
        "city": "Nellore",
        "country": "India",
        "state": "Andhra Pradesh"
    }
}

You will get response code 201 and new_url in response header.

Prevoius                                                 Next                                                 Home

No comments:

Post a Comment