Test Secure REST services with Chrome Browser Plugin

Most of us want to test out the REST services via Advanced Rest Client or Postman for some reason or debug an issue.

But if the REST services are secure and protected by Ping Access or SiteMinder or any other tool, then we will get a login page. So we have to hard code the browser cookies to bypass the login page.

There is an another way to do that.

If you are using Advanced Rest Client(https://advancedrestclient.com), then you can use ARC cookie exchange plugin.
So this plugin helps ARC plugin to retrieve the browser cookies and send it in the request.

If you are using Postman(https://www.getpostman.com), then you can use Postman interceptor. So the Postman interceptor plugin helps the Postman plugin to use the browser cookies for each service call.

HTTP Caching in REST API

In this post, I am going to show an example which explains the implementation of HTTP caching in REST API.

As we know that REST API services can be cached in the browser whereas SOAP based services are not.

We have two kinds of cache control mechanism

1. Time based cache header
2. Conditional cache header

Time based cache header

Assume that we have a web service and you want to cache the response of that service in client’s browser for 5 min. So to achieve the same, we should have to set the cache control HTTP header appropriately

Cache-Control:private, max-age=300

Here “private” denotes that the response will be cached only in the client mostly by browser and not any intermediate proxy servers

max-age denotes that how long the resource is valid. The value should be given in seconds

Conditional cache header

With the conditional cache header approach, the browser will ask the server whether the response/content has been changed or not. Here the Browser sends out ETag and If-Modified-Since headers[Need to set If-Modified-Since at the client API] to the server and at the server side we should use these headers and implement our logic and send out the response only if its changed or the client side content has been expired.

You can note for the first time, we get the HTTP status 200 and for the subsequent request, we get the HTTP status 304 Not Modified

Please refer the below sample code which shows both approaches

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.CacheControl;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;

public class GreetingResource {

    private static final String HELLO_MESSAGE= "Welcome %s";

    private static final String BIRTHDAY_MESSAGE= "Happy Birthday %s";

    private Request request;

    public Response sayWelcomeMessage(@QueryParam("name") String name) {
        System.out.println("sayWelcomeMessage:::::"+ System.currentTimeMillis());
        CacheControl cacheControl = new CacheControl();
        Response.ResponseBuilder builder = Response.ok(String.format(HELLO_MESSAGE, name));
        return builder.build();

    public Response sayBdayWishesMessage(@QueryParam("name") String name) {

        System.out.println("sayGreetingMessage:::::"+ System.currentTimeMillis());
        CacheControl cacheControl = new CacheControl();
        //60 seconds

        String message = String.format(BIRTHDAY_MESSAGE, name);
        EntityTag entityTag = new EntityTag(Integer.toString(message.hashCode()));
        //Browser sends ETag. So we can use this and
        // find out whether the response is expired or not
        Response.ResponseBuilder builder = request.evaluatePreconditions(entityTag);
        // If the build is null, then the content dont match, so the response should be sent
        if (builder == null) {
            builder = Response.ok(message);
        } else {
        return builder.build();

Rest API to produce message to Kafka using Docker Maven Plugin

I have developed a simple REST API to send the incoming message to Apache Kafka.

I have used Docker Kafka (https://github.com/spotify/docker-kafka) and the Docker Maven Plugin(https://github.com/fabric8io/docker-maven-plugin) to do this.

So before going through this post be familiarize yourself with Docker and Docker Compose

Docker Maven Plugin[Docker Maven Plugin] provides us a nice way to specify multiple images in POM.xml and link it as necessary. We can also use Docker compose for doing this. But I have used this plugin here.

    1. Clone the project (https://github.com/dkbalachandar/kafka-message-sender)
    2. Then go into kafka-message-sender folder
    3. Then enter ‘mvn clean install’
    4. Then enter  ‘mvn docker:start’. Then enter ‘docker ps’ and make sure that there are two containers are running. The name of those containers are kafka, kafka-rest
    5. Then access http://localhost:8080/api/kafka/send?msg=test and confirm that you see message has been sent on the browser
    6. Then enter the below command and make sure that whatever message which you sent is available at Kafka[Kafka Command Line Consumer] or you can also consume via a Flume agent[Kafka Flume Agent Consumer]
docker exec -it kafka /opt/kafka_2.11- --zookeeper localhost:2181 --topic test --from-beginning

Transfer Encoding and Content Length

Chunked transfer encoding is a data transfer mechanism which enables the response from the server will be sent as a series of chunks to the client. The servlet container will decide whether to use Content Length or Chunked based on the response content size. If the response content size is  more than the actual buffer size, then it will use Chunked Encoding otherwise it will calculate the content length and add it in the response header. Usually if the response content is large data, then it will use Chunked transfer encoding and you would not see the content-length header

Restful web services: Handling exception with WebApplicationException

Most of us use the below approach in our Rest services for handling the error response.

public Response getContactsById(@QueryParam("userId") String userId) {
        try {
            Contact contact = new ContactService().getContactsById(userId);
         return Response.ok().entity(contact).type(MediaType.APPLICATION_JSON).build();
        } catch (Exception ex) {
            LOGGER.error("Exception happened while getting contact data", ex);
            Throwable rootCause = Throwables.getRootCause(ex);
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).

So in the above code, if there is any issue/exception, then we catch that exception and get the root cause of it and create a new Response object with that and send it as JSON.

We can use the WebApplicationException instead of catching that error and creating a response object.

Below is the example for handling the above with WebApplicationException.

public class ContactNotFoundException extends WebApplicationException {

    public ContactNotFoundException(String message) {

public Response getContactsById(@QueryParam("userId") String userId) throws ContactNotFoundException {
        try {
            Contact contact = new ContactService().getContactsById(userId);
            return Response.ok().entity(contact).type(MediaType.APPLICATION_JSON).build();
        } catch (Exception ex) {
            LOGGER.error("Exception happened while getting contact data", ex);
            throw new ContactNotFoundException(ex.getMessage());

So in the above example, we create a custom exception ContactNotFoundException which extends the WebApplicationException. Inside the constructor, we create a response with proper status code and error message.

So in our Resource class, we use handle the exception and instead of creating a Response object, just throw the ContactNotFoundException with the message in it. Once we do this, then Rest of things are handled by Jersey framework itself.

Jersey – Rest – POJO mapping error

I have recently created a Jersey Rest application with Jetty and faced an issue while POJO mapping.

The exception trace is given below,

[INFO] No Transaction manager found - if your webapp requires one, please configure one.
[INFO] Initiating Jersey application, version Jersey: 2.6 2014-02-18 21:52:53...
[WARNING] unavailable
MultiException stack 1 of 3
	at com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider.setConfiguration(AbstractJAXBProvider.java:113)
	at com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider.setConfiguration(JSONRootElementProvider.java:86)

After carefully analyzing by running mvn dependency:tree, I have come to know that in my pom.xml, I included the below dependency which has caused this issue


The issue is because of the jersey-core.jar. By removing the above dependencies fixed the issue. Make sure to include all the relevant jackson jars for POJO Mapping