In this article by Alex Antonov, the author of the book Spring Boot Cookbook – Second Edition, learn to use and configure spring resources and build your own Spring-based application using Spring Boot.
In this article, you will learn about the following topics:
(For more resources related to this topic, see here.)
We will look into enhancing our web application by doing behavior tuning, configuring the custom routing rules and patterns, adding additional static asset paths, and adding and modifying servlet container connectors and other properties, such as enabling SSL.
When we build web applications, it is not always the case that a default, out-of-the-box, mapping configuration is applicable. At times, we want to create our RESTful URLs that contain characters such as . (dot), which Spring treats as a delimiter defining format, like path.xml, or we might not want to recognize a trailing slash, and so on. Conveniently, Spring provides us with a way to get this accomplished with ease.
Let's imagine that the ISBN format does allow the use of dots to separate the book number from the revision with a pattern looking like [isbn-number].[revision].
We will configure our application to not use the suffix pattern match of .* and not to strip the values after the dot when parsing the parameters. Let's perform the following steps:
@Override
public void
configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(false).
setUseTrailingSlashMatch(true);
}
Let's look at what we did in detail. The configurePathMatch(PathMatchConfigurer configurer) method gives us an ability to set our own behavior in how we want Spring to match the request URL path to the controller parameters:
If you want to do further configuration on how the path matching takes place, you can provide your own implementation of PathMatcher and UrlPathHelper, but these will be required in the most extreme and custom-tailored situations and are not generally recommended.
It is possible to control how our web application deals with static assets and the files that exist on the filesystem or are bundled in the deployable archive.
Let's say that we want to expose our internal application.properties file via the static web URL of http://localhost:8080/internal/application.properties from our application. To get started with this, proceed with the steps in the next section.
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/internal/**").addResourceLocations("classpath:/");
}
The method that we overrode, addResourceHandlers(ResourceHandlerRegistry registry), is another configuration method from WebMvcConfigurer, which gives us an ability to define custom mappings for static resource URLs and connect them with the resources on the filesystem or application classpath. In our case, we defined a mapping of anything that is being accessed via the / internal URL to be looked for in classpath:/ of our application. (For production environment, you probably don't want to expose the entire classpath as a static resource!) So, let's take a detailed look at what we did, as follows:
Another very common scenario in the enterprise application development and deployment is to run the application with two separate HTTP port connectors: one for HTTP and the other for HTTPS.
Another very common scenario in the enterprise application development and deployment is to run the application with two separate HTTP port connectors: one for HTTP and the other for HTTPS.
For this recipe, we will undo the changes that we implemented in the previous example. In order to create an HTTPS connector, we will need a few things; but, most importantly, we will need to generate a certificate keystore that is used to encrypt and decrypt the SSL communication with the browser.
If you are using Unix or Mac, you can do it by running the following command:
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
On Windows, this can be achieved via the following code:
"%JAVA_HOME%binkeytool" -genkey -alias tomcat -keyalg RSA
During the creation of the keystore, you should enter the information that is appropriate to you, including passwords, name, and so on. For the purpose of this book, we will use the default password: changeit. Once the execution is complete, a newly generated keystore file will appear in your home directory under the name .keystore.
You can find more information about preparing the certificate keystore at https://tomcat.apache.org/tomcat-8.0-doc/ssl-howto.html#Prepare_the_Certificate_Keystore.
With the keystore creation complete, we will need to create a separate properties file in order to store our configuration for the HTTPS connector, such as port and others. After that, we will create a configuration property binding object and use it to configure our new connector. Perform the following steps:
custom.tomcat.https.port=8443
custom.tomcat.https.secure=true
custom.tomcat.https.scheme=https
custom.tomcat.https.ssl=true
custom.tomcat.https.keystore=${user.home}/.keystore
custom.tomcat.https.keystore-password=changeit
@ConfigurationProperties(prefix = "custom.tomcat.https")
public static class TomcatSslConnectorProperties {
private Integer port;
private Boolean ssl= true;
private Boolean secure = true;
private String scheme = "https";
private File keystore;
private String keystorePassword;
//Skipping getters and setters to save space, but we do need them
public void configureConnector(Connector connector) {
if (port != null)
connector.setPort(port);
if (secure != null)
connector.setSecure(secure);
if (scheme != null)
connector.setScheme(scheme);
if (ssl!= null)
connector.setProperty("SSLEnabled", ssl.toString());
if (keystore!= null &&keystore.exists()) {
connector.setProperty("keystoreFile",
keystore.getAbsolutePath());
connector.setProperty("keystorePassword", keystorePassword);
}
}
}
@Configuration
@PropertySource("classpath:/tomcat.https.properties")
@EnableConfigurationProperties(WebConfiguration.TomcatSslConnectorProperties.class)
public class WebConfiguration extends
WebMvcConfigurerAdapter {...}
@Bean
public EmbeddedServletContainerFactory servletContainer(TomcatSslConnectorProperties properties) {
TomcatEmbeddedServletContainerFactory tomcat = new
TomcatEmbeddedServletContainerFactory();
tomcat.addAdditionalTomcatConnectors(
createSslConnector(properties));
return tomcat;
}
private Connector
createSslConnector(TomcatSslConnectorProperties
properties) {
Connector connector = new Connector();
properties.configureConnector(connector);
return connector;
}
In this article, you learned how to fine-tune the behavior of a web application. This article has given a small gist about custom routes, asset paths, and amending routing patterns. You also learned how to add more connectors to the servlet container.
Further resources on this subject: