Spring Boot on Scala

programming, Scala, Spring Boot, Uncategorized

Using Spring Boot on Scala

Assumption

This example uses a project generated/seeded via Activator using the “minimal-scala” template. However, any project using SBT will probably work just as well.

Add Spring Boot to dependencies

Add Spring Boot dependencies to build.sbt:

libraryDependencies += "org.springframework.boot" % "spring-boot-starter" % "1.3.2.RELEASE"
libraryDependencies += "org.springframework.boot" % "spring-boot-starter-test" % "1.3.2.RELEASE"

Create a SpringBootApplication and run it

package com.example

@SpringBootApplication
class HelloApp {

}

object Hello {
 def main(args: Array[String]): Unit = {
   SpringApplication run classOf[HelloApp]
 }
}

This class serves as a package “anchor” for component scanning. The singleton exports an equivalence of a “public static void main(String args[])” entry point.

At this point, “sbt run” will bring up the app, but it will quit soon afterward.

Time to decide if this will be a Web app or a Command line app.

Branch to Web or Command line (console)

Web app

To create a Web app, add the spring-boot-starter-web dependency. Add this to build.sbt:

libraryDependencies += "org.springframework.boot" % "spring-boot-starter-web" % "1.3.2.RELEASE"

That’s it! Now running “sbt run” will bring up the Web app listening on port 8080.

Command line app

To create a command line app (or to add a command line runner to a Web app such as above), modify the main app class:

@SpringBootApplication
class HelloApp extends CommandLineRunner {
  override def run(args: String*): Unit = {
    println("Hello from Command line runner!")
  }
}

Extending CommandLineRunner in Scala is the same as implementing CommandLineRunner in Java. So just implement the run method.

Try Autowiring something

Assuming the app class is com.example.HelloApp. The component scanning starts at com.example. So create a service class under that package (or a subpackage thereof). I will create one under com.example.services:

package com.example.services

import org.springframework.stereotype.Service

@Service
class HelloService {
  def hello(): String = {
    "Hello from HelloService!"
  }
}

Autowire into a bean using the service (HelloApp in this example):

@SpringBootApplication
class HelloApp extends CommandLineRunner {

  @Autowired
  var helloSvc: HelloService = null

  override def run(args: String*): Unit = {
    println(helloSvc.hello())
  }
}

Configuration properties

Configuration properties can go into src/main/resources/application.properties, same as in Java world:

titlemsg=Hello App

Accessing properties is also pretty much the same (e.g. shown here using @Value):

@SpringBootApplication
class HelloApp extends CommandLineRunner {
  ...

  @Value("${titlemsg}")
  var titleMsg: String = null

  override def run(args: String*): Unit = {
    println(titleMsg)
  }
}

There are several implementations of the @Value annotation available, be sure to use the one from Spring:

org.springframework.beans.factory.annotation.Value

Logging

And logging. Adding src/main/resources/logback.xml will allow tweaking of logging behavior:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <logger name="com.example" level="DEBUG"/>
</configuration>

I use Log4j, so here’s how to add a logger into the class to log with:

class HelloApp extends CommandLineRunner {

  val logger = Logger getLogger classOf[HelloApp]

  override def run(args: String*): Unit = {
    logger info "Hello using logger"
  }
}

 

Spring Boot using multiple datasources

Java, programming, Spring Boot

I cannot believe how little info there is on using multiple Datasources in Spring Boot. Out of the box, Spring Boot makes it very easy to configure the default Datasource: tweak a few properties for spring.datasource.* and I’m done.

However, if I want to use multiple datasources, very little documentation/instruction is available. The pieces are all there, but there is just no documentation. Even Manning’s Spring Boot in Action doesn’t have anything on the topic.

Well. After some searching and experimenting, I finally figured it out. Here are my findings: http://www.therealvan.com/multidsdemo.html

 

Spring Boot Command Line program

programming, Spring Boot

Command line program w/ Spring Boot

To write a command line program (e.g. launched w/ static void main(String args[])), have the main application class implements org.springframework.boot.CommandLineRunner and implement the function:

public void run(String... args) throws Exception
Running the program can be done with:
java -jar myjar.jar args... 
or with:
 mvn spring-boot:run -Drun.arguments="args..."
See Link to stackoverflow.
One oddity is that, when looking at the logs, the actual running of the program looks like it all happens within the initialization phase of the program:
  .   ____          _            __ _ _
 /\ / ___'_ __ _ _(_)_ __  __ _    
( ( )___ | '_ | '_| | '_ / _` |    
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |___, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.2.4.RELEASE)

2015-08-19 16:11:20 INFO  MyApplication:47 - Starting MyApplication on ...2015-08-19 16:11:20 DEBUG MyApplication:50 - Running with Spring Boot v1.2.4.RELEASE, Spring v4.1.6.RELEASE
2015-08-19 16:11:20 INFO  AnnotationConfigApplicationContext:510 - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@6fa107f2: startup date [Wed Aug 19 16:11:20 PDT 2015]; root of context hierarchy
2015-08-19 16:11:20 INFO  ProfilesConfigFileLoader:185 - Skip unsupported property name region in profile [default].

... program runs here ...

2015-08-19 16:11:23 INFO  MyApplication:56 - Started MyApplication in 3.484 seconds (JVM running for 7.704)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

Spring boot w/ Thymeleaf, jQuery & jQuery UI, and Bootstrap

programming, Spring Boot, Uncategorized

A more typical/modern setup would be to replace JSP with one of the template engines and JS and styling libraries:

Add Thymeleaf to Dependency

Add this to the project POM:

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

Installing files

jQuery

Copy into src/main/resources/static/js/ the downloaded jquery-a.b.c.js (or jquery-a.b.c.min.js)

jQuery UI

  • Copy into src/main/resources/static/js/ the downloaded jquery-ui.js (or jquery-ui.min.js)
  • Copy into src/main/resources/static/css/ the downloaded jquery-ui*.css
  • Copy into src/main/resources/static/css/ the images subdirectory itself (i.e. as src/main/resources/static/css/images)

Bootstrap

Copy into src/main/resources/static/ the three subdirectories from the Bootstrap distribution:

  • css
  • fonts
  • js

Include the files into templates

This can be done per-template, but probably easier to have a fragment that templates can call.

Start with a fragment file

Create fragment template such as src/main/resources/templates/fragments/js.html

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="bootstrap">
    <link rel="stylesheet" href="/css/bootstrap.min.css"/>
    <script src="/js/bootstrap.min.js"></script>
</div>
<div th:fragment="jquerys">
    <link rel="stylesheet" href="/css/jquery-ui.css"/>
    <script src="/js/jquery-1.11.2.min.js"></script>
    <script src="/js/jquery-ui.min.js"></script>
</div>
</body>
</html>

NOTE the two jquery libraries are combined into one fragment “jquerys”. They can be broken up as needed.

Reference various fragments in templates as needed

E.g. from src/main/resources/templates/index.html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
...
<div th:include="fragments/js :: jquerys"></div>
<div th:include="fragments/js :: bootstrap"></div>
....

Spring Boot w/ JSP

Java, maven, programming, Spring Boot

Project Setup

From the CLI or http://start.spring.io/, initialize a project with “web” capability.  What ends up happening is addition of the dependency:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Start with this directory structure. Be sure the controller (and any other Spring beans) are located under where the Application class (JspDemoApplication in this example) is.

...
  src/
    main/
      java/
        org/
          van/
            jspdemo/
              JspDemoApplication.java
              controller/
                DemoController.java
      resources/
        application.properties
      webapp/
        WEB-INF/
          jsp/
            demoindex.jsp

Controller and View

Add a controller file DemoController.java (see tree above for location):

...

@Controller
@RequestMapping("/jspdemo")
class DemoController { 
  @RequestMapping("/index")
  public String index(@RequestParam("name") String name, Model model) {
    model.addAttribute(name.toUpperCase());
    return "demoindex";  // view/JSP name
  }
}

Then the view file demoindex.jsp (see tree above for location). NOTE that the webapp/WEB-INF/jsp subdirectory needs to be created.

<html>
  <div>
    Hello, ${name}.
  </div>
</html>

Add support for JSP

Add these dependencies:

<dependency>
  <groupId>org.apache.tomcat.embed</groupId>
  <artifactId>tomcat-embed-jasper</artifactId>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>jstl</artifactId>
  <scope>provided</scope>
</dependency>

Add these to application.properties:

spring.view.prefix: /WEB-INF/jsp/
spring.view.suffix: .jsp