Restful web services: Handling exception with WebApplicationException

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


@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/contacts")
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).
                    entity(rootCause.getMessage()).type(MediaType.APPLICATION_JSON).build();
        }
    }

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) {
        super(Response.status(Status.NOT_FOUND).entity(message)
                .type(MediaType.APPLICATION_JSON).build());
    }
}


@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/contacts")
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.

Post Redirect Get Pattern

This is one of the web design pattern which is used to prevent the double form submission issue.

In the old days, when we design an application with JSP’s, we often face double form submission issue. So one of the best way to avoid this to disable the submit button as soon as the submit button is clicked. But if we show the result on same JSP page, then if the user refreshes the browser, then the form will be submitted again which cause some undesirable issues.

To avoid these kinds of errors/issues, we may need to change the API/server code to validate the request and some custom states. So it requires some unnecessary state maintenance in the server side.

Post Redirect Get pattern comes to the rescue in this kind of situation. Please refer the below diagram.

350px-PostRedirectGet_DoubleSubmitSolution

 

Here in this case, As soon as the user submits the form, the server does the operation on the backend and also forces the browser to redirect to a confirmation page. So if the user refreshes the confirmation page, then it would not have any impact as it will not do any operation other than showing the confirmation page.

But we have to keep in the below points along with this pattern.

  1. Disable the Submit button as soon as the user clicks on it
  2. If the server takes long time to respond back with the confirmation page and user tries to stop the browser and refresh the page in the mean time, then it will cause some other issues. So to handle these kind of issues, we have to either maintain some state and by checking this we can prevent the double submission issues.

 

Productivity : Stay Focused

In our day to life we keep on checking Facebook, Twitter and other entertainment sites.

We can’t control our mind by not checking on these sites. Due to this our productivity comes down drastically. If we get distracted by anything, then our mind will take lot of times to concentrate on that task.

There is a plugin called Stay Focused in Chrome which helps us to limit the amount of time spending on the social and entertainment sites. Once we install the plugin, we have to add the websites to be blocked in the settings and also configure the max allowable timing. Once the the max time reached, then you wont be able access those blocked sites in Stay focused. All those web sites are blocked by this plugin which help us to stay focus on our work.

Refer the below link,

Stay Focused

Productivity: Pomodoro Technique

The Pomodoro Technique is a time management method developed by Francesco Cirillo in the late 1980s

We can use this technique for managing our tasks. So there are six steps in this technique. They are given below

  1. Decide on the task to be done.
  2. Set the pomodoro timer (traditionally to 25 minutes).
  3. Work on the task until the timer rings. If a distraction pops into your head, write it down, but immediately get back on task.
  4. After the timer rings, put a checkmark on a piece of paper.
  5. If you have fewer than four checkmarks, take a short break (3–5 minutes), then go to step 1.
  6. Else (i.e. after four pomodoros) take a longer break (15–30 minutes), reset your checkmark count to zero, then go to step 1.

You can use the system timer or there are lots of Chrome plugin or apps available which you can use.

To name a few, Time doser, Pomodoro Timer, Simple Pomodoro and Strict Workflow

KanbanFlow app is integrated with Pomodoro timer. So we can easily manage our time with the KanbanFlow app.[https://chrome.google.com/webstore/detail/kanbanflow/hhhlbmjihokflibmbfmldajolmkaemhi?hl=en-US]

Docker Custom container Name

We use Docker compose for multi container application. After starting all the containers, then if you run the docker ps, you will be able to see all the containers and its images and port details.

If you note down the container name, its something generated by Docker. If we want to use the custom name, then we should specify it as container_name in the Docker compose file. Refer the below example,


rest:
   image: rest_image:1.0
   container_name: mywebApp-rest 
   environment:
      log_driver: "json-file"
   ports:
     - 8081:8081
   log_opt:
      max-size: "10m"
      max-file: "5"    

web:    
    image: web_image:1.0
    container_name: mywebApp-web
    environment:
     - REST_URL=http://rest:8081
    log_driver: "json-file"
    ports:
      - 80:80
    log_opt:
       max-size: "10m"
       max-file: "5"
    links:
         - rest:rest

If you use docker-maven-plugin[https://github.com/fabric8io/docker-maven-plugin], then you have to specify the alias inside the tag. Specify it as below


 <run>
  <namingStrategy>alias</namingStrategy>  
  ...
  ...
   </run>

Copy File/Directory with Maven resource plugin

We can use Maven resource plugin to copy files and directory to any folder/path. Please refer the below snippet from pom.xml. This will be used to copy the config files from ${project.build.directory}/config to /opt/config folder.


 <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.7</version>
        <executions>
          <execution>
            <id>copy-resources</id>
            <phase>package</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>/opt/config</outputDirectory>
              <resources>
                <resource>
                  <directory>${project.build.directory}/config</directory>
                  <filtering>false</filtering>
                </resource>
              </resources>
            </configuration>
          </execution>         
        </executions>
      </plugin>

Riak pluggable backend

Riak supports pluggable backend which means we can choose the different storage back end according to our needs. We have the below storage backends

  • BitCask
  • LevelDB
  • Memory
  • Multi

BitCask
Bitcask is an Erlang application that provides an API for storing and retrieving key/value data using log-structured hash tables that provide very fast access.

By default Riak uses this storage back end. The major weakness in this storage back end is key storage behavior. It maintains all the keys in memory all the time which means that the riak node must have enough memory to contain your entire keyspace, plus additional space for other operational components and operating- system-resident filesystem buffer space

LevelDB

eLevelDB is an Erlang application that encapsulates LevelDB, an open-source, on-disk key/value store created by Google Fellows Jeffrey Dean and Sanjay Ghemawat.

LevelDB is a relatively new entrant into the growing list of key/value database libraries, but it has some very interesting qualities that we believe make it an ideal candidate for use in Riak. LevelDB’s storage architecture is more like BigTable’s memtable/sstable model than it is like Bitcask. This design and implementation provide the possibility of a storage engine without Bitcask’s RAM limitation

Reading is slow when the levels are more which is the major weakness when using this storage

Memory
All data is stored in memory tables and the data will never be persisted into the disk or any other storage. It uses Erlang Ets tables to manage data

Multi
Riak allows us to run multiple backends within a single Riak cluster. We can store each bucket into a different memory storage. Any combination of the three available backends—Bitcask, LevelDB, and Memory—can be used.

We can create a different bucket type and specify the backend and finally create a bucket and assign the appropriate bucket type. In this way we can leverage the multiple backend option

Deploy war on Jetty Server

In this post, I am going to show how to deploy a war file on Jetty Server.

For this exercise, I have taken the sample.war file from Tomcat web site. Please refer https://tomcat.apache.org/tomcat-6.0-doc/appdev/sample/

Once you have downloaded the sample.war file, then it’s time to create the Dockerfile.

Create a Dockerfile and copy the below content in it.


FROM jetty
ADD sample.war /var/lib/jetty/webapps/root.war
EXPOSE 8080

Then it’s time to build and run the docker container.

Build the container:


docker build -t jetty .

Run the container:


docker run -p 8080:8080 jetty

Then access the browser and check http://localhost:8080/hello. You will be able to see the welcome message.

Java String Join – Different ways

When we develop a web application, a lot of times,  we may need to join a list or an array with a space of comma. In Java, we have to write boilerplate code to do that.

To get rid of those, we can use the Apache common utils or guava utils. Refer the below code. It’s pretty simple if we use those utils effectively. Humans tend to make errors. So if we write the code for ourselves, we may cause some issues while doing those. All these utils and its methods are thoroughly tested and verified. So it’s good to use these unless reinvent yourself.


import com.google.common.base.Joiner;
import org.apache.commons.lang3.StringUtils;

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

public class StringJoinUtils {

    public static void main(String[] args) {
        List stringList = new ArrayList(Arrays.asList(new String[]{"Apple","Orange","Banana"}));
        //Apache commons
        System.out.println(StringUtils.join(stringList, ":"));
        //Guvava utils
        System.out.println(Joiner.on(":").join(stringList));
        //Java 8
        System.out.println(String.join(":", stringList));
    }
}


If we use Java 8, we can use the String.join method.