bryanlcampbell.com

Spring Boot, Spring 4 - Blog Building Part 1

Bryanlcampbell.com was built from scratch easily on top of Spring and many other open source libraries.  This article is the first of many to outline each piece that went into making this blog.  Creating anything with new libraries is usually a challenge due to lack of documentation.  Suprisingly, it was also more fun than usual, since many features built into Spring Boot make development easier than before.

Spring Boot

Spring has grown a LOT.  One can get confused looking at documentation from different versions and seeing all the libraries and tools that spring has to offer.  Spring Boot is Spring's way to make using Spring easier in general.  It bundles a lot of common functionality together and allows you to easily choose what you want to use.  Spring Boot will detect your applications needs based on annotations, beans, and configuration and will do most of the work for you.  Usually there is a fair amount of redudant configuration need for a web application... but guess what.. most of them you don't have to anymore.  This site's code is actually very small... almost 3K lines in total.  Here is Spring's "How do I do that FAQ".

Spring Framework 4

Many of the new features in Spring Framework 4, are sprinkled in Spring Boot.  Beyond that it includes:

  • Support for Java 8 features
  • Groovy Bean Definitions
  • Core Container Improvements, including new bean annotations of course: @Description, @Ordered, @Conditional
  • Further web support: @RestController annotation, WebSocket, SockJS, and STOMP Messaging
  • Many other features

So.. 

Let's Get Started

Setup

Fire up your favorite IDE or text editor.  Create a new maven project.  Let's start off creating a pom with the following configuration.

pom.xml

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.0.0.RC1</version>
</parent>
<properties>
	<start-class>com.bryanlcampbell.blog.Application</start-class>
</properties>
<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
</dependencies>
<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
		<plugin>
			<artifactId>maven-compiler-plugin</artifactId>
			<configuration>
				<source>1.6</source>
				<target>1.6</target>
			</configuration>
		</plugin>
	</plugins>
</build>
<repositories>
	<repository>
		<id>spring-snapshots</id>
		<url>http://repo.spring.io/libs-snapshot</url>
		<snapshots>
			<enabled>true</enabled>
		</snapshots>
	</repository>
</repositories>
<pluginRepositories>
	<pluginRepository>
		<id>spring-snapshots</id>
		<url>http://repo.spring.io/libs-snapshot</url>
		<snapshots>
			<enabled>true</enabled>
		</snapshots>
	</pluginRepository>
</pluginRepositories>

Above you will notice a few things.  The parent of this project is spring-boot-starter-parent.  This is the main ingredient for any Spring Boot project.  I included the web package since this is a website that we're biulding.  You should also note the Application class path that is stored in the start-class property. 

Create a Spring Application class

src/main/java/blog/Application.java

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application 
{	
	public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Simple so far right?  Here is the application class that the pom referred to.  When this project is exectured, it will run this main method which will start our Spring application.  It doesn't look like much, but honestly this is where all the magic begins.  Normally in a web application you need a web.xml, application context, etc... Not here.  The @EnableAutoConfiguration scans the project for beans you may need and will auto generate them for us.  So no more declaring obvious configuration.  @ComponentScan tells Spring to look in other similar packages for configuration classes with beans. 

Well then... Let's add some bean based configuration

src/main/java/blog/config/WebConfig.java

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

	@Value("${service.port}")
	private Integer servicePort;
	
	@Bean
	public EmbeddedServletContainerFactory servletContainer() {
		TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
		factory.setPort(servicePort);
		factory.setSessionTimeout(10, TimeUnit.MINUTES);
		factory.addErrorPages(
				new ErrorPage(HttpStatus.BAD_REQUEST, "/not-found"), 
				new ErrorPage(HttpStatus.FORBIDDEN, "/not-found"), 
				new ErrorPage(HttpStatus.NOT_FOUND, "/not-found"), 
				new ErrorPage(HttpStatus.METHOD_NOT_ALLOWED, "/not-found")
		);
		return factory;
	}

}

In this configuation I am extending the WebMvcConfigurerAdapter in order to reach the embedded tomcat settings.  In this article we will produce two things: a welcome page, and a not found page.  Instead of having Tomcat serve its normal happy messages of misfortune when a browser goes to an nonexistant page, I wanted to serve up my own content instead.  The port is also set here.  Notice the @Bean annotation?  No more creating beans in an xml file.  Also for the @Value annotation, this value is injected based on a properties file.

Controller Creation

src/main/java/blog/controller/BlogController.java

@Controller
public class BlogController {
	
	@RequestMapping(value="/", method = RequestMethod.GET)
	@ResponseBody
	public String homePage() {
		return "<html><body>Hello <b>World</b></body></html>";
	}

}

src/main/java/blog/controller/ErrorHandlingController.java

@Controller
public class ErrorHandlingController {
    
	@ResponseStatus(HttpStatus.NOT_FOUND)
	@ResponseBody
	@RequestMapping("/not-found")
	public String pageNotFound() {
		return "<html><body>Sorry, page not found.</body></html>";
	}
    
}

Above you can see two different examples of controllers.  One is handling all error pages, and the other handles normal blog activity.

Create a Properties File

src/main/resources/application.properties

service.port=8090 

This properties file is automatically loaded by Spring Boot.  The service.port value is then injected to the WebConfig servicePort property.  And that's that.  All done, you can compile and run this project and it should work as expected.  You should receive a nice hello on the root, and a sorry on any other page.

Run the web app

mvn clean install
java -jar target/spring-blog-part1-setup-spring-1.0.0-SNAPSHOT.jar

To run it as a jar type: java -jar [jar file location]

Congratulations! Next we will go over Thymeleaf integration.

 




Comments

--> -->