Skip to main content

Welcome to Geoff Hayward's Weblog

Commenting on Java, JavaFX, Java EE, Joomla, and IoT.

When an exception is thrown server side it is often desirable to let the user know what went wrong. When working with JAX-RS it is surprisingly simple to send a user-friendly error responds. In this post I will show you how simple it can be.

If you are reading this I assume you have some familiarity with JAX-RS (hopefully Java EE), Bootstrap, JQuery, and with a bit of luck Knockout JS. If you don't, well you soon will.

JAX-RS Mapped Exceptions

With JAX-RS when an endpoint is called that results in an exception, the developer can map the exception to a response. You, the developer, map exceptions by implementing the ExceptionMapper generic. Here is an example:

@Provider
public class ConnectExceptionMapper implements ExceptionMapper<ConnectException> {

    @Override
    public Response toResponse(ConnectException ex) {
        return Response
                .status(Response.Status.GATEWAY_TIMEOUT)
                .entity(new ErrorMessage("Connection Error", ex.getLocalizedMessage))
                .build();
    }
}

A Java EE application container uses the @Provider annotation to link-up the mapping. The response , in this example, sets a '504 Gateway Timeout' status, and takes an entity. The entity is an important element in this example; it will become the user-friendly error message.

The ErrorMessage entity is ordinary but I will include it for completeness.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class ErrorMessage {
    
    private String title;
    private String body;

    public ErrorMessage() {
    }

    public ErrorMessage(String title, String body) {
        this.title = title;
        this.body = body;
    }

}

The @XmlRootElement is used by JAX-RS via JAXB to format the object. The response format in our case will be assumed as JSON. The format is usually determined by the subject JAX-RS endpoint using the @Produces annotation.

The Web UI

Next you will need to create an HTML5 page. Add the following libraries: Bootstrap, JQuery, and Knockout JS.

The Knockout JS

Knockout JS is very lean; here is the only Knockout JS JavaScript that you need for this example (other than the binding):

var ErrorMessagesViewModel = function () {
    this.list = ko.observableArray([]);
};

This JavaScript is a ViewModel that holds a list. The list is a Knockout JS 'observableArray', so that the error messages can be pushed onto the list.

Next add the Knockout JS view. Knockout JS applies the 'alert-template' to each item in the list.

<div data-bind="template: { name: 'alert-template', foreach: list }">
    <!-- KO dynamic -->
</div> 

In this example I opted for a Knockout JS view template, as I do not like to see a 'flash' load. A 'flash' load would briefly show the view on a page loads then hide it.

Here is the 'alert-template':

<script type="text/html" id="alert-template">
    <div class="alert alert-warning alert-dismissible" role="alert">
        <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <strong data-bind="text: title"></strong>
        <br />
        <span data-bind="text: body"></span>
    </div>
</script>

The template is the closable Alert from Bootstrap. The message's title and body are the variables within the template.

Next we will construct the ViewModel and bind it.

var messages = new ErrorMessagesViewModel();
ko.applyBindings(messages); 

As you can see the constructed ViewModel is assigned to a variable named 'messages'. In the next section JQuery will use the 'messages' variable to push server error responses.

The JQuery

JQuery's AJAX utility can catch global events. We are going to catch global error events. Here is the JQuery:

$(document).ajaxError(function (event, response, settings, thrownError) {
     messages.list(response.responseJSON);
});

That's it, as long as you are using JQuery's AJAX utility, such as '$.getJSON' to send requests the JAX-RS mapped exceptions are pushed on to the list and shown to the users.

As an aside the solution in this example is an aspect, in the AOP sense. The 'ErrorMessagesViewModel' is a modularisation of concern.

Video Supplement

This post is an after the fact note on a solution from a project I am working on. So here is a video of this solution in action within the other project.



Read

Here is how you can create a WebSockets base path for your JavaScript with JSF. This WebSocket base path points back to your deployed application's WAR address.

<script type="text/javascript">
	var base = "#{request.scheme.endsWith("s") ? "wss" : "ws" }://#{request.serverName}:#{request.serverPort}#{request.contextPath}";
</script>

I hope this helps.



Read

The ever growing social media buttons are request culprits! But you can reduce the request they make and style social media buttons your way by following this simple article.

What Makes Social Media Buttons Request Heavy?

The social buttons are not only requested via your webpage; they are also requesting their own assets once they have loaded. This means several requests are made for each button. Each of these request are slowing down your web page's loading speed.

Creating a GET request that mimics the request that each social media button's JavaScript would otherwise construct will keep the extra requests made down to zero. If the button is clicked only then will a request be made.

How Can I Style Social Media Buttons?

As you are creating the mark-up for the button yourself, you are free to style the link as you wish. Tip: to keep the requests down, add the network's logos to your image sprite.

It is worth noting: the user interaction design principle of continuity. The principle's sub-principle of external continuity would suggest styling the buttons to look like the network's own buttons. Following this principle would suggest your users will already know what your buttons do and how to use them.

Here are Template Links for Social Buttons

Just swap out the UPPER CASE placeholders below . Don't forget to URI encode your variables.

Facebook

http://www.facebook.com/sharer.php?s=100&p[title]=YOUR_TITLE&p[summary]=YOUR_SUMMARY&p[url]=YOUR_URL&p[images][0]=YOUR_IMAGE_TO_SHARE_OBJECT

Twitter

https://twitter.com/intent/tweet?hashtags=A_HASH_TAG&related=RELATED&text=YOUR_TITLE&url=THE_PAGES URL&amp;via=THE_CLIENT_HANDLE

Linkedin

http://www.linkedin.com/shareArticle?mini=true&url=URL&title=YOUR_TITLE&summary=YOUR_SUMMARY&source=THE_CLIENT_NAME<

Google Plus

https://plusone.google.com/share?url=URL

For the maximum effect combine these links with open graph and twitter cards. Twitter lets you use Open Graph where a meta tag exists. This is good as you get a twitter card as a bonus when adding Open Graph. Here is the perfect mix of the two.

The following template needs to be added in the <head> of the HTML document.

<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@ TWITTER NAME ">
<meta name="twitter:creator" content="@ TWITTER NAME ">
<meta property="og:title" content="">
<meta property="og:image" content=" AN IMAGE ADDRESS ">
<meta property="og:site_name" content=" SITE NAME ">
<meta property="og:description" content="">
<meta property="og:url" content="">
<meta property="og:type" content="article">

Add the following to each link and you will get the buttons to open in a small window just like how the social network's own buttons work.

onclick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"


Read

This article is written to impart a short cut in getting to the content of an XML document from within a JavaScript script quickly and consistently across browsers. You will see that by skipping the XML document's DOM all together time and bytes are saved.

There is also a second good to the solution that is conveyed in this article. To the best of my knowledge earlier than ie9 versions of Internet Explore do not treat RSS feeds as XML. This means in an Ajax's XMLHttpRequest object there is no responseXML document to work with and that can be a gotcha. Of course you may be able to change the header for RSS documents server side. However let's assume you cannot get access to do so as this article is about dealing with XML responses generally.

Getting the Text from XML the Normal Way

When the XMLHttpRequest object of an Ajax call returns with a responseXML you have a document. A handsome document full of information but, getting hold of the information is not so easy. There are traversals to make you dizzy, elements to store, and then there are cross browser issues for getting hold of the text nodes themselves.

An XML Traversal Example:

var items = responseXML.getElementsByTagName('item');
var title[3] = items[3].getElementsByTagName("title")[0];
var desc[3] = items[3].getElementsByTagName("description")[0];

And in reality there will be a for-each loop or for loop in there somewhere. There will be variables storing elements – allsorts going on. It may not be the hardest thing to do but the JavaScript file is growing byte by byte and the cross browser issues are afoot.

The XML Text Node Cross Browser Issue

Some browsers get hold of the text node like this:

.textContent
Others browsers get hold of the text node like this:

.text

This means making a function that will return the content whichever way the browser likes to work is a likely root. In other words, more bytes are added to the JavaScript file just to deal with cross browser differences. It is at this point you realise you are not working smart and are going down the wrong root. But, there is the better solution.

Getting the Text from XML the Smart Way

While the DOM is normally a good thing in this case it only serves to get in the way. Introduce regular expressions to the mix and add a little responseText and your smart cake is well on its way to tasty.

You may ask: What about the lack of single line mode in JavaScript's regular expression? And I would say good question. The answer is 'no problem' and it is all thanks to:

[\s\S]

This means from the group, denoted by the square brackets, of white space characters and not white space characters. That's right anything and including new line characters.

The example below uses regular expression to collect all the items from an RSS feed into an array. Then it takes the index for getting a random item. It then templates the item as appropriate and finally appends the templated item into the DOM of the main HTML page.

new Request({
    'url': '/testimonials.rss',
    onSuccess: function(responseText){
        //split items into an array 
        var items = responseText.match(/<item>[\s\S]*?<\/item>/g);
	
        // pick an item at random 
        var rand = Math.floor(Math.random()*items.length);

        // template the data 
        var html = '';
        html += /<div class="feed-description">(.*)<\/div>/.exec(items[rand])[1];
        html += '<p class="title">' + /<title>(.*)<\/title>/.exec(items[rand])[1] + '</p>';
        html += '</div>';

        //then wrap and append it to something 
        var testimonial = new Element('div', {
           'class': 'testimonial'
        }).set('html', html);
        $$('.testimonials')[0].grab(testimonial, 'bottom');
    }
}).send();

You can of course template all the items of the feed or nodes of your document the first few items or whatever you need. Using the same method you can get hold of any part of the item or whatever your XML document is. For example:

html += '<a href="' + /<link>(.*)<\/link>/.exec(items[rand])[1] + '">Read more</a>';

will add a link back to the article source as given in the RSS feed.

Conclusion

As XML is often the transport medium given in response to many Ajax requests, it is important to have a good cross browser solution that doesn't necessarily weight down the scripts size. This method is a way of dealing with what has been returned across all browsers without the need of extra functions that only serve to make your solution work a cross browsers. I am finding this approach works very well and it is worth sharing. What do you think about this approach?



Read

At the time of writing this article I have not seen websites with completely successful attempts at loading icons which appear when html anchor tags are clicked. I therefore decided to find my own solution.

By completely successful I mean the website continues to function as if the icons where not there at all. For example pressing 'Ctrl' and left clicking the link of an anchor tag a new tab should appear within the user's browser. The original tab from which the click was initiated should remain the same.

At no time should the loading icons prevent the default behaviour of the browser. Not when it is a link away from the page either internally or externally relative to the website. The reason being: You do not want to upset search engine spiders, accessibility etc.. Remember we are trying to enhance the website's usability without taking anything away.

The CSS Problem with Anchor Tags Loading Icons

The main problem I had to overcome first was: Browsers, with the exception of Firefox, just do not request images from the server once a page has received an anchor click that goes to a new page. So how do we solve a problem like this? The solution is to already have the requested loading icon image before the anchor tag is clicked.

So now the question becomes: Where to hide the loading icon ready for the click of the anchor tag? I admit I got very inventive whilst experimenting with this problem. However, the solution I found and settled on was simple. That is to simply hide the loading icon on the anchor itself. In other words the icon is always there with a negative 100% on the x-axes. Then all that needs to be done is shift the position of the loading icon image into view once you need it. So now the CSS class called 'loading' is put into the stylesheet ready for action.

.menu a {
    background: url("../images/loading.gif") no-repeat scroll -100% 50% transparent;
}
.menu a.loading {
    background-position: 100% 50%;
}

Solved! Or is it? That at least solves the CSS part of the loading icons on the anchor tag problem.

JavaScript for Anchor Tags Loading Icons

Now all we need to do is to shift the x-axes of the loading icon image by adding the class named 'loading' to the anchor when clicked. This of course, is easier said than done.

Sticking to the discipline that HTML provides structure, CSS provides presentation and JavaScript provides behaviour all the JavaScript in the solution I found loads from a JS file.

The first thing the solution needs to do is to wait for the DOM to be loaded. It then needs to find all the anchor tags that are going to have loading icons. Once it has found the anchor tags, it needs to add a click event. As this is pretty standard functionality given by JavaScript abstraction layers, I made my life easier by using Mootools. However, there is nothing library specific in the solution that I am giving here. Prototype JS, jQuery, etc. will work just fine.

So the click event! This is the tricky part that can stop the user's browser working as it should. When the anchor is clicked, we add the class named 'loading' to the anchor tag. However, the 'Ctrl' click, 'Alt' click and 'shift' click need to not have an effect when the event is fired. So an if not statement needs to wrap around the event to stop the class 'loading' being added.

For example:

if(!event.control && !event.alt && !event.shift){
  node.addClass('loading');
}

That is all there is to it! It was easy once I solved it.



Read

Mailing List

Responsive Media

With the ResponsiveMedia plugin for Joomla it is easy to add 3rd party content from YouTube, Vimeo, and Instagram right in to any Joomla! article.

ResponsiveMedia