Spring Boot is changing the world of Java development with Spring. It is taking away much of the pain that was involved with configuring applications. This is great when you are trying to create what they do by default. They create executable jars by default. What do you have to do if you need to create a WAR file to run on a Tomcat by someone else.
Let’s start with our project’s pom.xml file. Here we need to define the standard Spring Boot parent starter and also include include the Spring Boot Web starter. The Spring Boot Web starter also includes the Spring Boot Tomcat starter. In our case, we do not want it packaged inside our war because our war file will be deployed on a Tomcat server directly. We don’t have to roll our own. To change this behavior, we include the Spring Boot tomcat starter explicitly and set it’s scope to provided. We also must specify the packaging of our project to be a war.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javaninja.springboot</groupId> <artifactId>springboot-web</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
Normally the Java Configuration contains a main method because that is how the program will be launched. In this case, we do not need a main method and instead we need to provide a configure method to go along with the SpringBootServletInitializer that we extend.
package com.javaninja.springboot.web; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; @SpringBootApplication public class WebApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(WebApplication.class); } }
That is all of the configuration that we need to make this work as a normal Spring MVC controller. To test our functionality, we need a very simple controller, such as the following,.
package com.javaninja.springboot.web; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ExampleController { private Logger log = LoggerFactory.getLogger(getClass()); @GetMapping("/example/boolean") public Boolean exampleBoolean() { log.info("Eureka!"); return true; } }
Let’s create a very simple test using the Spring Boot Test starter. This brings in Junit and MockMvc among other useful APIs.
package com.javaninja.springboot.web; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import static org.assertj.core.api.Assertions.fail; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * @author norris.shelton */ @RunWith(SpringRunner.class) @WebMvcTest(ExampleController.class) public class TestExampleController { @Autowired private MockMvc mvc; @Test public void testExampleBoolean() { try { mvc.perform(get("/example/boolean") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string("true")); } catch (Exception e) { fail(e.toString()); } } }
The test run perfectly and produces the following logging and a nice pretty green bar.
2017-07-10 18:36:06.218 INFO 7499 --- [ main] c.j.springboot.web.ExampleController : Eureka!
sheltonn July 11th, 2017
Posted In: Maven, MockMVC, Spring, Spring Boot, Spring MVC, Test Driven Development, Unit Tests
Tags: Spring, spring boot, spring boot web