Thursday 11 December 2014

Tips for RESTful web apps using Servlets

Here are a few tips on how to make the most of the Servlet container's natural RESTful architecture.
  1. Let each servlet represent a 'resource' in your system. You can then override the doGet(), doPost(), doDelete() etc methods to add possible operations, if that resource needs to support them.
  2. HTML forms that perform changes on the server must use the POST method and links to read-only pages and search forms must use the GET method. Most browsers won't let you use PUT or DELETE as form methods, so these type of calls need to be made via AJAX.  If you try to use the body of the http call to pass parameters, these will be ignored by the server unless you are using POST. So PUT, GET and DELETE calls need to pass all their information in the URL.
  3. You can make pretty urls by using the URL mapping provide by the servlet container but you can only use the wildcard * at the end of the URL pattern. This means you can't use the URL to pass hierarchical information. So for example you would have to use app/papers/16 rather than apps/users/jsmith/papers/16. A hierarchical URL is not necessary for RESTful architecture anyway, since REST does not dictate any URL format.
  4. Any URLs used by your system should be devised on the server and passed down to the client as links or form actions. This ensures a clean separation of client and server, allowing you to change the format of the urls without changing the client code too much.

Friday 28 November 2014

Things I wish that Javascript did better in the browser: AJAX

I've been trying to write the shortest possible generic function that I can call to make an AJAX request. My best attempt is around 100 lines of code. Here's the basic code:

var el = document.getElementById("message"); 

var xmlHTTP = new XMLHttpRequest(); 

xmlHTTP.open(method, "service/messages", true); 

xmlHTTP.onreadystatechange = function() { 
 if (xmlHTTP.readyState == 4 || xmlHTTP.readyState == "complete"){ 
  el.innerHTML=xmlHTTP.responseText ;
 } 
};

xmlHTTP.send(body);

The first problem is that the event listener onreadystatechange is far to broad so it ends up always having to hold conditional logic. How about an onready listener instead?

Secondly, the stateful XMLHttpRequest object could pass a reference to itself or a separate response object to the listener.

Thirdly, I don't see why the XMLHttpRequest can't have a another constructor that allows you to pass in the url and the onreadystatechange (or onready) function:

new XMLHttpRequest("my-service-endpoint",onready); 

Also as well as the open() method, we could have get() post() and del() methods:

new XMLHttpRequest("my-service-endpoint",onready).get(); 
new XMLHttpRequest("my-service-endpoint",onready).del(); 
new XMLHttpRequest("my-service-endpoint",onready).post(body);

These are minimal changes to the existing api which would allow us to make AJAX calls in one statement:

var el = document.getElementById("message"); 
new XMLHttpRequest(
 "service/messages",
  function(response){ 
      el.innerHTML=response.text; 
  }
).get();

Update: Looks like they have started to deal with the first issue by adding an onload event. It would nicer still to be able to pass this as a constructor argument in XMLHttpRequest. http://www.html5rocks.com/en/tutorials/file/xhr2/

Monday 22 September 2014

Servlets as First-Class Citizens - MVC Pattern Without a Web Framework

The MVC pattern is the idea of separating the implementation of a user interface into three parts. The Model, the View, and the Controller. This separation helps avoid spaghetti code that can arise from trying to write a single entity which represents all of these roles at once, or splitting the roles unthinkingly among various entities.


  • The Model is the data being held by the system. Data that the user might want to add to, remove, edit etc.
  • The View is essentially the part that the user sees and interacts with. The View controls how the application looks, and exposes the Model and functionality to the user. 
  • If the user interacts with the View, any interactions are delegated to the Controller. The Controller must update the Model with the changes that the user is requesting, and get the View to update itself based on the updated Model.

The Model: Pojos

In many cases there are two models: that which is used by the client-side code, and the data that is held in the application database. It is the Controller's job to get data from the database and reformat it to better match the particular View that is requested. This adaptation of the Model can be used to simplify the logic which generates the View. It also allows the design of User Interface to be more separate from the design of the back-end storage, since data from many tables can be fetched efficiently and combined into a single Model per interface.

The View: JSP 

The View can be generated using JSPs.  Using JSTL tags, data from the Model can be used to render an HTML page or fragment that exposes the data to the user and controls how it is displayed including executing logic that controls the display of role-restricted elements. Once generated, the View should be essentially dumb, and not contain JavaScript code or in-line event listeners.

The Controller: Servlets + JavaScript

Due to the nature of the web, the Controller must be split between the server and the client. Client-side controller code is written in JavaScript and is responsible for handling events generated by the browser as the user interacts with the client-side interface, and calling the server-side code. The server-side controller code will be split into various components responsible for performing updates to the database, and fetching data to be passed back to the View.

Many frameworks (sometimes called action-based frameworks) use a front-controller which is a Servlet or Filter that handles all incoming requests and directs them to Java classes which represent either actions or views. The mapping between the URL and the action is then controlled by the framework, which must read this information from somewhere such as configuration files, a database table or annotations on the action classes themselves.

With Servlet Annotations introduced in Servlet 3.0, this front-controller is no longer needed since annotations can be added to the Servlets. Therefore in a framework-free application, Servlets become first-class citizens once more, mapping themselves to URLs that can be called by the client-side controller code.

On the client-side, often JavaScript libraries such as jQuery are used to set up event listeners which bind the application controller code to the native browser components. In modern browsers, these libraries are becoming unnecessary since the Event API of HTML has been standardized to allow easy binding of event listeners, and native methods have been added to the HTML DOM API to allow fast searching of the DOM tree for the components on which to listen for events.



Thursday 18 September 2014

Changing Servlet Form-based Authentication to Single Page

If you want to implement Form-based Authentication in a Java web application there are a few tutorials that show you how such as:

http://www.informit.com/articles/article.aspx?p=24253&seqNum=5

These type of posts show you the basics and work well but what you will end up with is a login page where users attempt to log in, and an error page where users are redirected if there is an error. This is really annoying for users, since if they mistype their username or password they are redirected to a page where they then have to follow a link back to the login page.

If you just want to use the out-of-the-box security for example provided by Tomcat, you will have to have two separate jsps, but there is no reason why the error jsp can't simply forward to the login page:

login-invalid.jsp:

<jsp:forward page="login.jsp"><jsp:param value="true" name="invalid"/></jsp:forward>

login.jsp:

<c:if test="${param.invalid}">
<div>
Sorry, that login was not recognised, please log in again.
</div>
</c:if>
<h3>Log in</h3>
<form method="post" action="${ctx}/j_security_check">
<div>
<label for="j_username">Email:</label>
<input type="text" name="j_username">
</div>
<div>
<label for="j_password">Password:</label>
<input type="password" name="j_password">
</div>
<div><input type="submit" value="Enter"/></div>
</form>

Tuesday 19 August 2014

Lean Servlet Application Manifesto (work in progress)


Lean Servlet Applications:

  1. Are highly modular.
  2. Have a source hierarchy that is easy to understand and navigate.
  3. Are packaged by functionality not by layer.
  4. Have the minimum number of third party dependencies.
  5. Are built directly on top of the Servlet API. For instance, they implement their own Servlets and do not rely on a Controller Servlet to handle all incoming requests, or any intermediate Filters to wrap or preprocess the Request.
  6. Are designed to make it fast to build out more functionality (even things that had never been previously envisaged)
  7. Behave predictably and fail loudly.
  8. Are fast to build and deploy, and perform well.
  9. Are not obsessed with being REST-ful, but like to keep their URLs logical and readable. They do not abuse the HTTP GET method.
  10. Make the most of AJAX for a great user experience, but are not single-page Javascript applications.

Rules for developing Lean Servlet Applications:

  1. All HTML must be generated from JSPs (or other templates). This means Servlets are not used to output HTML directly to the client, and no JSP tags are used to output HTML. Adding dynamically to the HTML DOM by JavaScript code is also kept to an absolute minimum, other than inserting pre-rendered HTML generated by a JSP.
  2. No pages in the application link directly to JSPs, always to a Servlet which forwards to the JSP.
  3. All application-wide Filters and Servlets such as error handlers are defined explicitly in web.xml.
  4. Business/functional Servlets are not defined in web.xml but are mapped using Servlet 3.0 annotations.
  5. Any shared or generally useful jar dependencies should be moved to the container's lib directory in order to keep the application WAR files as lightweight as possible. If this is too difficult to manage with Maven (or other prescriptive build tool), then don't use it.
  6. Exceptions should be handled by the container, not by each individual Servlet.
  7. The WebContent directory should be organised by functionality, so each module has its own directory with all its web resources and jsps. The top level should contain application-wide jsps and shared web resources. No separate folders for style sheets, images or JavaScript source files.




    Thursday 5 June 2014

    Lean Servlet System

    Today I've uploaded the code that has been born out of this blog to GitHub. I've called it the Lean Servlet System.

    https://github.com/Si-Kelly/LeanServletSystem


    Tuesday 15 April 2014

    Exception Handling and AJAX in a Java Servlet Container

    The Servlet Spec provides a simple way to implement error pages for different types of exceptions that might be thrown by your application with the <error-page> element in your web.xml. However, just like container managed security, you need to make some small changes if you want to handle AJAX requests differently.

    Once again this technique relies on your being able to differentiate AJAX requests from full page requests. In my app I have taken a conscious decision to make sure that any requests that are made asynchronously use a URL containing '/ajax/'. This simplifies life quite a lot, but if you don't want to do this you could use a query parameter such as ?ajax=true on all AJAX requests.

    The simplest use-case is that you want to catch all exceptions thrown at runtime and forward the user to an error page if they are making a normal http request, and return a small snippet of error message if they are making use of some asynchronous functionality.

    In this case you can put this in your web.xml:

      <error-page>
        <exception-type>java.lang.Throwable</exception-type>
        <location>/error</location>
      </error-page>


    Then to handle the errors you would create a small servlet like this:

    @WebServlet("/error")
    public class ErrorServlet extends HttpServlet {
     @Override
     public void service(
      HttpServletRequest request, 
      HttpServletResponse response
     )throws ServletException {
      String uri = (String) request
        .getAttribute(
          RequestDispatcher.ERROR_REQUEST_URI
        );
      if (uri != null && uri.contains("/ajax/")) {
       response.setStatus(
        HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
       request.getServletContext()
        .getRequestDispatcher("/error.jsp")
        .forward(request, response);
      } else {
       request.getServletContext()
        .getRequestDispatcher("/error-page.jsp")
        .forward(request, response);
      }
     }
    
    }
    
    
    In a nutshell this code will forward to a jsp called error-page.jsp if the request is a normal http request. In the case of an AJAX request it returns an HTTP status code 500 and forwards to a different jsp that generates snippet of html with the error message, in case the JavaScript on the client wishes to display a message.

    Of course you may want to handle different types of errors differently, which can be done using the configuration in web.xml to specify another Servlet. I handle validation errors from forms submitted via AJAX separately but in a similar way to this, putting the name of the fields and the messages in an object to be serialised to JSON, allowing the client to handle highlighting error fields and displaying messages.