Serving static content in Spring Boot
last modified July 6, 2020
Spring Boot static content shows how to serve static content in a Spring Boot application.
Spring is a popular Java application framework. Spring Boot is an effort to create stand-alone, production-grade Spring based applications with minimal effort.
Spring Boot automatically adds static web resources located within any of the following directories:
- /META-INF/resources/
- /resources/
- /static/
- /public/
The directories are located in the classpath or in the root of the ServletContext
.
In our application, we have one HTML file which contains a simple link. The link triggers a response from the web Boot application. It returns a plain text message.
pom.xml src ├───main │ ├───java │ │ └───com │ │ └───zetcode │ │ │ Application.java │ │ ├───controller │ │ │ MyController.java │ │ └───model │ │ Message.java │ └───resources │ │ application.properties │ └───static │ │ index.html │ └───css │ main.css └───test └───java └───com └───zetcode └───controller MyControllerTest.java
This is the project structure of the Spring Boot application.
<?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.zetcode</groupId> <artifactId>springbootstaticex</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> </parent> <dependencies> <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> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
This is the Maven build file. The spring-boot-starter-web
is starter for
building web applications using Spring MVC. The spring-boot-starter-test
imports necessary testing modules. The application is packaged into a JAR file.
package com.zetcode.model; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class Message { @Value("${app.message}") private String message; public String get() { return message; } }
Message
is a model class which contains a simple text
messate for the client.
@Value("${app.message}") private String message;
We inject a value from the application.properties
into the message
variable.
app.message=Hello there
The application.properties
file contains various configuration settings of a Spring Boot
application. We define a custom property having a text message.
package com.zetcode.controller; import com.zetcode.model.Message; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class MyController { @Autowired private Message message; @GetMapping(path = "/message") @ResponseBody public String message() { return message.get(); } }
This is the controller class for the Spring Boot web application. A controller is decorated with
the @Controller
annotation. The controller has one mapping; it is mapped to
the /message
path and returns a plain text message.
@Autowired private Message message;
A Message
object is injected into the property.
@GetMapping(path = "/message") @ResponseBody public String message() { return message.get(); }
The message()
method responds to a GET request. The @ResponseBody
annotation puts the string value to the web response body.
<!DOCTYPE html> <html> <head> <title>Home page</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="css/main.css" rel="stylesheet" type="text/css"> </head> <body> <h2>Home page</h2> <a href="/message">Get message</a> </body> </html>
In the index.html
file we have a link that invokes a response from
the web application. The file is located in the src/main/resources/static
directory,
which is a default directory where Spring looks for static content.
<link href="css/main.css" rel="stylesheet" type="text/css">
In the link tag we refer to the main.css
static resource, which is
located in the src/main/resources/static/css
directory.
h2 { color: blue }
In the main.css
file, we set the h2
tag to blue colour.
package com.zetcode.controller; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 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.forwardedUrl; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; @RunWith(SpringRunner.class) @SpringBootTest public class MyControllerTest { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; @Before public void setup() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); } @Test public void getHome() throws Exception { this.mockMvc.perform(get("/")) .andDo(print()) .andExpect(status().isOk()) .andExpect(forwardedUrl("index.html")); } @Test public void getMessage() throws Exception { this.mockMvc.perform(get("/message")) .andDo(print()) .andExpect(status().isOk()) .andExpect(content().string("Hello there")); } }
In the MyControllerTest
we have two tests: one for the home page
and one for the returned message text.
package com.zetcode; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
The Application
sets up the Spring Boot application. The @SpringBootApplication
annotation enables auto-configuration and component scanning.
In this tutorial, we have served static context in a Spring Boot application.