Adding The People By Location Controller

Now that we have the main landing page of the application created it is time to build our next page. To start the process of I have gone to VSTS and dragged the ‘See All Staff In A Single Location’ story over to the Active column.

I can now return to IntelliJ and start building my next controller. I’m going to add a new controller class to the application called LocationController. Don;t forget to annotate the called with the @Controller annotation so that Spring MVC will pick it up correctly.

The @RequestMapping annotation is set as /location/{id}. This part in the curly brackets is a dynamic mapping so that the request mapping will match a url like /location/PA or /location/NY etc. You can, in theory, match multiple parts of the incoming request so that something like /location/{state}/{city} would match a url of /location/pa/pittsburgh.

To extract the value that is being passed in on the dynamic RequestMapping you use the @PathVariable annotation in the methods signature.In this case I’m extracting ‘id’ from /location/{id}. if I was writing a signature to match the state/city example above I would write something like location(@PathVariable(“state”) String state, @PathVariable(“city”) String city, ModelMap model).

You will also notice I have autowired in the two repositories in my application and I’m adding all the locations in to the model just as I did with the main landing page (because the list of locations is displayed on all pages) and I have added a call to my personRepository that will return all the people in the specified location.

Next I’ll add this info to a html template called location.html

Advertisements
Tagged with: ,
Posted in Domino To Spring, None

Adding Locations Data To The UI

Now that we have our demo data and we have confirmed that it exists when we start the application it is time to add it to the Thymeleaf based UI.

First we need to add it to the data model that is used when the page is rendered. If we return to our HomeController class we need to make a couple of changes. First we need to get access to the LocationRepository bean. We do this by adding an Autowired reference the bean using the same method that we did when building the demo data.

Then we need to add this to the model. The model is pretty much a java map of strings and objects. In the highlighted line below you can see that I’ve used the model.addAttribute method to create an entry called ‘locations’ and the object passed in to that attribute is the findAll() method of the locationRepository.

Now we need to turn our attention to the thymeleaf html page. I’ve added a bunch of other Bootstrap related changes to give the application a basic layout and I’ve decided that the list of locations should appear in the side navigator. I’m building a standard bootstrap styled navigation with some extra Thymeleaf magic.

In my LI tag I have a th:each attribute. This is similar to a repeat control in xpages and is written like a loop in java. the ${locations} is  the locations attribute from the model and the th:each will loop through them using a variable name of ‘location’ for each iteration.

In the A tag I have a th:href that contains a thymeleaf expression that will be converted to a url. While it may look a little complex its not really that difficult. Firstly the expression is surrounded with @{…} this tells the thymeleaf renderer that the url being generated is absolute to the base of the application. This allows you to move the application on an application server to a different subpath and none of the paths in the application will break. Next is the reference to the html page that is going to be displayed next /location.html. After that is a section in round brackets, anything in here will be converted to parameters on the url and the path surrounded with the ${…} is a reference back to the loops variable and in this case we are pulling the id from the object.

So the th:href will be translated to /location.html?locationId=xx where xx depends on the selected location.

What if you don’t want location.html in the url and want to do something like /location/XX in that case your th:href would look like

I’m going to leave it like this for my application so that I can show you a great feature in the Spring MVC request mapping controllers next but for now I’v completed my first task of showing a list of the location on the main home page of the application. I can now return to VSTS and drag that card over to the done column and see what is next up to do.

So looks like I’ll be building the location page so that you can see all the staff in a single location. I’ll drag that over to Active and start work on it next.

Tagged with: , , , ,
Posted in Domino To Spring, None

Checking Your Demo Data

Now that we have the demo data how do we know that it is actually working and getting in to the database. It would be rather pointless trying to add the data to the UI if there is no data to add.

If you are using a persistent datasource then you can just use whatever databases tools you normally use to check the tables, but in our case we are using an in-memory database that disappears when the application is exited. Thankfully, however, the H2 in-memory database does have an admin console and SpringBoot sets it up for you when you have the spring-boot-devtools dependency added to your pom.xml file.

To access the H2 Console just start the application in your IDE and then access the console URL and click the connect button. You should not have to change any of the details in the rest of the dialog box.

Once connected you should see your two tables in the left navigator. If you click on the table name the SQL command to view the contents of the table should appear in the command box, just click on Run to load the table.

And if everything is correct you should see your demo data appear.

Now we can finally start adding the data to the UI…

Tagged with: , ,
Posted in Domino To Spring, None

Adding Some Demo Data

Before we can start displaying data in our application we need to add some demo data. You could point the data source to be an external persistent data source that contains test data instead of using an in-memory data source that is lost each time to stop the application or you could load up the in-memory data source with demo data each time the application is started by using either a sql file containing statements to add the data or by writing a script that runs when the application starts that uses the repositories that we built earlier.

For this demo data I’m going to use the data repositories method as it is quick and easy and doesn’t require any sql knowledge.

Lets create a new class called DemoData that implements a Spring class called Application Runner. The class is also annotated with @Component which will allow it to be detected when the Spring Boot application starts.

Next we need access to the repositories. This is done by Autowiring them. Autowiring is a way to setup bean references in your code. Think of this as something similar to managed beans in XPages except you don’t need to edit any xml to get them working. Below is a constructor based autowire of the two repositories.

First I create two private variables in the class that will hold the beans. Next I create a constructor for the class that takes in a parameter for each bean I’m autowiring and then those to the private variables. Lastly I need to make sure I add the @Autowired annotation to the constructor. I could also have written the auto wiring as follows

but this is no longer recommended. If you see code examples like this then you can easily turn them in to constructor autowiring by allowing IntelliJ to convert them for you. Just click the code hint icon that appears when you click on the annotation and pick the constructor.

Now we just need a method that will run when the application runs. Because we extended ApplicationRunner there is a method that we can override called ‘run’ and then we can add as much data to the repositories as we like.

Here I have added one Location and one Person You can add as many as you want in your version. I do like the way that IntelliJ shows the argument names, this makes it really easy for when you next look at the code in a few months time.

One question you might ask yourself is how do we stop this ApplicationRunner from running once the application is in production as we would not want that data showing in that environment. The answer is simple and is all to do with Profiles. I’ll cover profiles in a later entry when we get around to deployments.

Now that we have data we can add it to our UI…

Tagged with: , , , ,
Posted in Domino To Spring, None

Adding Bootstrap To The Frontend

Web applications need more than just html. You also need CSS, JavaScript, Images maybe even Fonts. All of these can be added to the resources/static folder in your SpringBoot application. Here I have added a phonebook.css file that will hold the custom css needed for my application.

And then you can reference them in your html file.

If you look carefully you will notice that there are TWO references to my phonebook.css file. The first is a normal href and it points to a path relative to where my html file is. The second is the th:href which references the css file in a @{}. This is one of the powerful constructs provided by Thymeleaf. As a natural templating engine I could open the home.html file in my browser from the filesystem and it will resolve the correct path to the css file, however when it is rendered by the Thymeleaf processor the original href tag is overwritten by the th:href tag and the @{} rewrites the url to an absolute base path for the application.

I also want to add Bootstrap to my application. I COULD just drop the entire bootstrap archive in to the correct css/js/images/fonts folders and then reference them using links just as I did above for the phonebook.css file. There would be nothing wrong with doing this and it would work perfectly but there is a better way.

Spring Boot applications are setup to support WebJars. A WebJar is a Java ARchive that contains all the css/js/images/font resources that you need for a particular application. You can add it to your project by adding a dependency to the WebJar that you require directly to the projects pom.xml

I have added a dependency to bootstrap v3.3.7 and a dependency to JQuery 3.1.1. I’ve also told the bootstrap dependency to exclude its own dependency on JQuery as it is an older 1.11.x version and adding the exclusion will help reduce the final size of the application.

Now I can add references to these webjars to my html file

Again I’m using the double href method. One pointing to an online version of the webjar and the other pointing to the internal version of the webjar. However this still isn’t great. I have to reference the version numbers in both the pom.xml file and the html files. If I wanted to upgrade to a newer version of Bootstrap or JQuery I would have a lot of files to edit.

There is an easy solution to this. Just add the following dependency to your pom.xml file.

And then remove the version number from the Thymeleaf version of the links in your html file and when it is rendered the locator will automatically dd in the correct version number from the pom.xml file.

While this still don’t update the standard url’s you only really need to use those standard urls if you are developing the html files offline so if you just need to update to a newer version of Bootstrap or JQuery due to a security fix and your testing scrips are done using the running application there would be no need to touch the html files anyway.

Tagged with: , , , , ,
Posted in Domino To Spring, None

Starting The Frontend

For the frontend we are going to be using Thymeleaf. When you add Thymeleaf to your project using the spring-boot-thymeleaf-starter you will get support for both Thymeleaf V2.x and Thymeleaf V3.x. By default the V2.x support is activated by the starter but if you want to use V3.x then you can easily add some properties to your pom.xml file. I want to use V3…

Once you have updated the pom.xml file it it time to create the applications first page. This is done in the resources/templates folder and should be called home.html to match the string returned by the controller we created.

The html file is a standard html file but I have added a xml namespace declaration to the html tag to indicate that I’m using thymeleaf. This helps the IntelliJ html editor to provide extra hints and autocompletion for thymeleaf tags. I have not added any thymeleaf tags just yet but I will in the future. I would also suggest that you update your IDEs code template to add the tag there so that you don’t have to do it ever time in your projects.

If you were to run the application right now it would look fairly boring…

 

In the next part I will spruce it up a little by adding a simple Bootstrap layout..

Tagged with: ,
Posted in Domino To Spring, None

Controlling The Frontend

Before we can start building our frontend we need to tell our Spring Boot application how to handle the incoming requests and what html page to display. This is done using Spring MVC which we added when we picked the spring-boot-starter-web dependency in the Spring Initializer. This dependency adds a built in tomcat web server that is configured with a set of defaults and sets up the application to scan for special classes that have been annotated with @Controller

When a class is annotated with @Controller Spring MVC knows that it will contain methods that have been annotated in such a way that the method can be mapped to a specific request.

I’ve created a new package in my source to hold all my controllers called, you guessed it, controllers. In here I have created a new java class called HomeController and I have annotated it the @Controller annotation above the class name. I then added a single method to the class and I have annotated that with @RequestMapping(“/”) which means whenever a request comes in that matches the root of the site you should return the string ‘home’.

This returned string is intercepted by Spring MVC and is passed to the configured template renderer which in our case is Thymeleaf. Thymeleaf will then look in the resources/templates folder for a html file called home.html and will send that to the web browser.

If we were to run the application right now we would get an error as we don’t have that html file yet.

The other thing to notice is that the RequestMapping method accepts a ModelMap called model. This is where we can add data to the model so that when the Thymeleaf processor is rendering the page it can take the data from the model and slot it in to place, This is very like how an XPage application can put values in to the rendered html. Right now I’m not putting anything in to the model so I’ll come back to that later.

Tagged with: , ,
Posted in Domino To Spring, None
Archives