Mini Spring Boot Web Application

After a couple of years of reading about Spring Boot and never having actually tried it out, I thought now was the time to build a little example to find out how easy it is and also because I need a simple app for my E.L.K. project (more on that later!).

There’s a very good intro to get people off the ground from Spring on their website https://spring.io/guides/gs/spring-boot/ which I read through and then tweaked.

The source code for the rest of this blog article can be found here https://github.com/vls29/spring-boot-example.

For the web application I’ve used Maven, but instead of following the guide exactly as the guide extended the spring boot starter parent pom, I decided to find out what I might need to get the project to run by using only the poms/jars that I thought would be essential.

As such the pom doesn’t have a parent and references only the relevant spring boot related poms and jars:

  • spring-boot-starter-actuator to bring in the “…production grade services…” and see what they do!
  • spring-boot-starter-web to bring in all the Spring MVC and embedded tomcat goodies
  • and spring-boot-starter-log4j2 to add in logging which I’m going to need for the E.L.K. project

There’s also two plugins, the maven compiler plugin to make sure it compiles at Java version 8 and the spring-boot-maven-plugin as the guide mentioned that it bundles the jar with the included maven dependencies (note if you’re not extending the spring boot super pom, you’ll need an execution goal for the spring-boot-maven-plugin otherwise nothing will happen).

The Application and HelloWorldController are based around the example from the getting started guide, but the UserController is one I’ve added.  It has a noddy example service which receives a path variable long representing the id of the user to retrieve (although in the example it doesn’t matter what value!).  It constructs a static user and returns the user object to the consumer.  Spring MVC then uses Jackson to marshal the object to JSON.

The final file is then a Run Config for Eclipse which executes the “spring-boot:run” goal and starts up the app from Eclipse.

The result is a very simple service that can retrieve our fake user as shown in the image below.

spring-boot-example-1

I was pleasently surprised how quick it was to create a service and all the documentation available to set it up.

That’s it for now, but there will be more on E.L.K. soon!

Spring MVC with ExtJS (Sencha)

I’ve decided to post this example, even though I never actually did finish it. Its missing a form to post back a new temperature reading and save that posted value to the database. It also could do with refreshing the graph after the new value has been added to the database.

Anyway, the basics of the project are there. A Spring MVC web app with ExtJS (Sencha) front end showing a graph of the temperature records in the database.

Particular files of interest:

temperature.jsp – simply loads in the temperature.js script file and contains a div where the graph will be rendered.

<html>
 
	<head>
	    <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">
	    <script type="text/javascript" src="extjs/ext-all-debug.js"></script>
	    <script type="text/javascript" src="js/tempgraph.js"></script>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<script>
		Ext.onReady
		(
			function()
			{
				Ext.getCmp('tempChart').render('tempChartDiv');
			}
		);
		</script>
	</head>
	<body>
		<div id="tempChartDiv" style="width: 500px; height: 500px;"></div>
	</body>
</html>

tempgraph.js – contains all the necessary ExtJS code to render the temperature graph and request data from the database.

Ext.require('Ext.chart.*');
Ext.require('Ext.data.*');

function dateConversion(v, record){
	var dateAsString = v.toString();
	//2011-04-10
	console.log(dateAsString);
	var year = dateAsString.substr(0, 4);
	var month = dateAsString.substr(5, 2) - 1;
	var day = dateAsString.substr(8, 2);

	var date = new Date();
	date.setFullYear(year, month, day);
	
	return date;
}

//alert("here");
Ext.define('Temperature', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'id'},
        {name: 'averageTemperature', type: 'float'},
        {name: 'date', convert: dateConversion},
        {name: 'highestTemperature', type: 'float'},
        {name: 'lowestTemperature', type: 'float'}
    ]
});

var store = new Ext.data.Store({
    model: 'Temperature',
    proxy: {
        type: 'ajax',
        url : '/Temperature/temperatures.xml',
        reader: {
            type: 'xml',
            root  : 'temperatures',
            record: 'temperature'
        }
    },
    autoLoad: true
});

var chart = new Ext.chart.Chart ({
	id: 'tempChart',
    width: 500,
    height: 500,

    store: store,
    animate: true,
    
    // Set a legend
    legend: {
        position: 'left'
    },
    
    // Define axes
    axes: [
        {
        	type: 'Numeric',
        	minimum: 0,
            position: 'left',
            fields: ['averageTemperature', 'highestTemperature'],
            title: 'Temperature',
            minorTickSteps: 1,
            grid: {
                odd: {
                    opacity: 1,
                    fill: '#ddd',
                    stroke: '#bbb', 'stroke-width': 0.5
                }
            }
        },
        {
        	type: 'Time',
	        position: 'bottom',
	        fields: ['date'],
	        title: 'Day',
	        dateFormat: 'd M',
	
	        //constrain: true,
	        fromDate: dateConversion('2011-04-08'),
	        toDate: dateConversion('2011-04-12')
        }
    ],

    // Define series
    series: [
        {
        	type: 'Line',
        	highlight: {
            	size: 7,
            	radius: 7
	        },
	        axis: 'left',
	        xField: 'date',
	        yField: ['averageTemperature'],
	        markerCfg: {
	            type: 'cross',
	            size: 4,
	            radius: 4,
	            'stroke-width': 0
	        }
        },
        {
        	type: 'Line',
        	highlight: {
            	size: 7,
            	radius: 7
	        },
	        axis: 'left',
	        xField: 'date',
	        yField: ['highestTemperature'],
	        markerCfg: {
	            type: 'cross',
	            size: 4,
	            radius: 4,
	            'stroke-width': 0
	        }
        }
	]
});

Other than those two files, the rest can be found in the project zip, Temperature.zip, MD5 hash ee60b90609c2e1654dfd179bed11cebe. Feel free to extend it or even finish it off 🙂

Example of the output:

Spring MVC project with XML output – (pre-post)

This is a pre-post to the complete project which I’ve been working on. The complete project is a very simple Spring MVC project which records temperatures and outputs the data on a graph. I just couldn’t wait to post this though, as quite frankly, it’s cool and saves sooo much time creating XStream objects.

Instead of creating loads of XStream objects to represent your xml in/output, Spring MVC with Java 1.6 does all the work for you with just a few simple steps.

In your servlet.xml file, E.g. temperature-servlet.xml, add a namespace for mvc and add the mvc:annotation-driven tag E.g.

<?xml version="1.0" encoding="UTF-8" ?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:oxm="http://www.springframework.org/schema/oxm"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
			http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd
			http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
	
	...
	
	<mvc:annotation-driven/>
	
	...
	
</beans>

In your controller all you need to do is create a method which returns the object you would like as the root element of your XML output, in your controller interface, E.g. in this case I’m returning a Temperatures object (which will be shown separately):

public interface TemperatureController
{
	...

	@RequestMapping(value = "/temperatures.xml")
	Temperatures temperatures();
}

In the controller implementation, the code looks like the following. I have retrieved a list of Temperature objects and added them to the Temperatures (not very original name) object:

@Controller
public class TemperatureControllerImpl extends AbstractController implements TemperatureController
{
	@Autowired
	private TemperatureService temperatureService;
	
	...

	/**
	 * {@inheritDoc}
	 */
	@ResponseBody
	public Temperatures temperatures()
	{
		final Temperatures temperatures = new Temperatures();

		invokeServiceMethod(new ServiceWrapper()
		{
			@Override
			public void executeMethod()
			{
				temperatures.getTemperature().addAll(temperatureService.getAllTemperatures());
			}
		});

		return temperatures;
	}
}

The Temperatures object is the root object being sent back to the consumer, so in order for Spring to be able to output it, the object needs a Jaxb @XmlRootElement annotation at the top of the class, E.g.

@XmlRootElement
public class Temperatures
{
	private List<Temperature> temperature;

	public void setTemperature(List<Temperature> temperature)
	{
		this.temperature = temperature;
	}

	public List<Temperature> getTemperature()
	{
		if ( temperature == null )
		{
			temperature = new ArrayList<Temperature>();
		}
		return temperature;
	}
}

Of course you need a little more than the above code to get a working project, but those are the key parts which allow Spring to output your xml when you call up a url, for example, in my above example, when requesting the url temperatures.xml.

Pretty cool really! And would have saved a good number of days on one project.