Sunday 22 June 2014

Validation handling for Post-Redirect-Get

There are plenty of descriptions of the Post-Redirect-Get pattern online, but I am bit surprised and disappointed to see that most descriptions do not bother to cover a validation path.

With the obvious exception of search forms, most of the forms that I encounter online or develop in my day job will involve some input validation so I am taking it as not being a moot point.

As a toy application we can think of a web application which prompts the user to enter their date of birth and then displays back some information about that date - it could be the person's current age or a mash up of other people born on the same day and important events for that date, use your imagination.

Let's consider the application as consisting of two views:

  • input form to accept the day, month and year
  • display interesting information about the date specified through the form
In this setup the Post-Redirect-Get pattern would work as follows:
  • Web browser HTTP GET request results in display of html page with the input form view.  The input form specifies method as POST and action as the appropriate form processing action on the server.
  • A form submission results in an HTTP POST request being sent to the server including any form values that have been populated.
  • In the Happy Days scenario a valid date has been specified, the server side action performs any necessary calculation or lookup and redirects the browser to a GET resource which will duly present the second view.  To avoid having to consider passing any state with the redirect this example application might embed the date into the resource URL - /doDateStuff/{yyyy}/{mm}/{dd} might work as a suitable resource URL pattern.

Now, what about the situation where an invalid date has been entered?  For example, 29 February 2015 is an invalid date because 2015 is not a leap year.

My preferred approach to this is to allow the POST request to provide a response with the input form view along with the validation error message(s).  In this path there is no redirect to a GET resource.  If the browser refreshes then the form submission will be repeated and the validation will fail again and the input form will show the error(s) afresh.

An alternative approach that I have never used in my 14 or so years of professional web development treats the Post-Redirect-Get approach as applying to validation.  In my opinion this approach involves additional complexity for carrying the validation state across to the request that the browser will send when it receives the redirect response.  The use of a short-lived cookie seems to be the hack for this.

Taking the non Happy Days scenario further, what happens if the user refreshes the invalid form?
  • In my preferred approach the browser will probably detect that a POST request is going to be repeated and present a dialogue asking if the user really wants to do that.  If the user accepts the warning and continues with the repeat submission then the form post is repeated, the validation is applied by the server and the same input form view response with the same validation error messages will show.
  • With the short-lived cookie approach the GET request will go to the server and the input form view will be rendered without the old error messages and without the values showing in the form  - because the short-lived cookie has been disposed of.


Tuesday 17 June 2014

Quick fixes - the road to pain

After adding some new dependencies to our application we discovered that the Cloud Foundry deploy would no longer work.  The error related to duplicate files being found in the jar file's manifest folder.

A pair of developers did some investigation, changed some config and "fixed" the issue - great.

Later in the day another pair decided to try actually making the application execute some of the new code's functionality in the cloud - just some relatively trivial calls to a RESTful service.  The unit tests had all worked in development and the continuous build pipeline so surely there won't be any problems?


BANG!
java.lang.NullPointerException
    at javax.ws.rs.core.MediaType.valueOf

For our application this was a runtime exception being thrown from a dependency of a dependency.

To cut a long story short, if your application needs to be deployed as one uberjar, don't blindly exclude configuration files from the resultant META-INF directory structure.  Some systems expect and require configuration to be in place.

For my team I expect this to act as some motivation to set up some automated smoke tests that will interact with the web application inside the Cloud Foundry environment.

Tuesday 10 June 2014

Java 8 Resources

This page mainly exists as a set of bookmarks for myself.

Java Magazine March/April 2014

Oracle Java tutorial
Online book
Third party blog posts
Videos

Monday 9 June 2014

Deploying a Play application into Cloud Foundry

A week or so ago some colleagues gave a brief introduction to the local Cloud Foundry environment.

One of the main takeaways for me was that our application would need to be able to bind to a TCP port specified at runtime rather than have a statically defined one from a config file.

We spent some time looking into how to tell Play to listen on a provided port, and what might be involved in setting up a Cloud Foundry manifest file - then decided to just try deploying with something that we expected to fail.

We were pleasantly surprised to discover that the Java buildpack included enough logic to detect our application as being a Play application and looked after the port binding for us.

It wasn't a completely smooth process, as we did have to update the JDK version in the buildpack - which involved forking the Cloud Foundry github repository.  Three lines of text changes was enough to get it up and running.