Donate profile for Rudi at Stack Overflow, Q&A for professional and enthusiast programmers

22/08/2015

487 views

Upgrading This Website


Upgrading to JavaEE - Spring Boot

In the unlikely event someone were actually following my ramblings, they would have noticed that I've not written anything for four months. To cut a long story short I changed jobs and got married, so I've been pretty busy. Also, and probably more relevantly, I had decided to write some work that would require a little more oomph from my website. I also wanted to make some upgrades that frankly plain html, css and javascript were not going to be capable of. I am writing this article now because I made those upgrades. So my first post will be about what I've done, all the cool technologies I used, and how I chose them.


So my new job was incredibly generous and bought me tickets to go to Devoxx 2015, which was awesome by the way. On the second day I sat in on a talk from Josh Long about Spring Boot and, like some kind of wizard, he threw together a website using Spring Boot in break-neck time and still managed to keep some witty banter going through-out. I'm a Java developer primarily so I already wanted to use JavaEE for this site and Josh made it look so easy with Spring Boot that I just had to try it for myself.


So that is what I did, I went to start.spring.io and chose all the technologies I wanted, clicked generate project, and was given a working basic set-up for my new Spring application. Less than an hour later I had a working version of my website up and running. I used Thymeleaf for my view layer, Maven for build dependency management, and later connected a MySQL database to the app. So, what exactly was it I wanted to do that required this much more comprehensive setup?


1 - Record and monitor unique views for each article.
2 - Have all articles displayed dynamically on the home page, ordered by date of publishing.
3 - Show off most popular articles using recorded data.
4 - Remove often repeated code, such as the header on each page.
5 - Create machine learning/neural net algorithms article.
6 - Set up subscriptions so that people can get email updates.
7 - Set up a donations service to help recover some costs.
8 - Set up article searching with keywords per article.

So, the above is my to-do list for the site. The first three on the list are done. If you look to the top right of the page you'll notice a views counter. In order to check whether views are unique I am simply creating a session for each user that visits an article (by creating a cookie on their side that has an ID I can recognise them by) and then logging the first time these sessions access each article. If you already have a log in the database showing you've viewed the article, your view wont be considered unique. If you refresh the page now, the view counter shouldn't go up. If you're using Chrome and you want to see this in action press F12 so the developer options pop up, click Resources and then Cookies. You should see the JSESSIONID that is used to check your visitor number, if you delete this cookie and refresh the page you will see the view counter go up again.


Each article on the site is now logged on the database the first time it is accessed, that way I can do all kinds of server side logic on them to speed things up in future or keep track of stats on each article. So the points 2 & 3 on the list were easy. For number 4 I have done some (but not all) of the work so far. I used a feature of Thymeleaf called Fragments. Using the header bar at the top of the website as an example we can declare it using all necessary markup and styling on one single page...


<div class="header" th:fragment="header">
   <div class="container">
      <a class="rklogo" href="/"></a>
      <a class="twitter" href="twitter.com/RudiKershaw"></a>
      <a class="linkedin" href="uk.linkedin.com/in/rudikershaw"></a>
      <a href="stackoverflow.com/users/2182928/rudi">
         <img src="..." width="208" height="58" />
      </a>
   </div>
</div>

... and then you can refer back to this on another page without having to repeat all the details. Notice, in the html above the th:fragment="header".


<div class="header" th:replace="/index :: header"></div>

This single line on each page basically translates as "replace this div with a copy of the div marked th:fragment='header' on the page /index". Not only do we save many, many lines of code on each page when you take into account headers, footers, navigation etc but it means that if you ever need to change them there is a single place you can go to edit those things for the whole website. Marvelous.


As for points 5 to 8; I will be adding those in at some point in the future. Wanting to get into machine learning was a large part of the reason for the upgrade and I want to write an article (hopefully soon™) about the most basic example of machine learning that can be talked about in a quick article. Then after that I'd like to try something a bit more robust.


Before I'm done, there are some fantastic features of Spring Boot that I just have to talk about briefly. The one that has to be mentioned first is that with Spring Boot your whole web application can be packaged into a single .jar file with everything inside, including an embedded Tomcat web server. What this means is that you don't have to set up a web server at all, you just build your application, and run the .jar file and that's it. Love it. I have already mentioned the start.spring.io page that let's you pick features that you want in your app and creates a starter pom.xml for you. This means, as was the case with me, that you can have a project up and running in no time at all. A lot of people will know Spring as a framework as having fairly verbose xml configuration for things like bean injection and the like but Spring Boot requires none at all. It is all handled through neat annotations. And then there are the usual benefits of frameworks such as 'intelligent defaults' and the like, etc.


An excerpt from the spring boot page.

Create stand-alone Spring applications
Embed Tomcat, Jetty or Undertow directly (no WAR file deploys)
Provide opinionated 'starter' POMs to simplify your Maven config
Automatically configure Spring whenever possible
Provide production-ready features such as metrics, health checks and externalized configuration
Absolutely no code generation and no requirement for XML configuration

And that's it from me for now. I hope this was helpful. Thanks for reading. If you have any criticism, corrections, objections, or (Gods forbid) praise just drop me a comment under the article, and until my next article, happy reading!


Rudi Kershaw

Web & Software Developer, Science Geek, and Research Enthusiast