Technology: Spring Boot is most popular framework used for developed applications. Spring Boot will provide Tomcat server by default. If we add spring-starter-web as dependency then Tomcat server will be added to classpath.Spring-boot-starter-tomcat will be added if we add spring-starter-web as dependency in pom.xml file.
Configuring Server Properties:
Spring-boot-autoconfigure jar file provides ServerProperties class using which we can provides properties to server like port, context-path of an application, SSL configuration etc…
ConfigurationPropertiesBindingPostProcessor will load all properties and assign properties to Java Properties and create the required beans.
Creating sample Rest application:
@SpringBootApplication public class SpringBootCustomDeploymentApplication { public static void main(String[] args) { SpringApplication.run(SpringBootCustomDeploymentApplication.class, args); } @RestController public class SampleController{ @GetMapping("/greeting") public Map<String,String> getGreetings(){ Map<String,String> map = new HashMap<String, String>(); map.put("Hello", "Greeting"); return map; } } }
If we run the application then tomcat server will run on port 8080 and run the application on root contextpath.
Running/deploying application on Jetty:
We can run/deploy the application on jetty server using spring-boot-starter-jetty dependency.
So we can remove the tomcat dependency and we can add spring-boot-starter-jetty dependency.
<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-jetty</artifactId> </dependency>
Using scope we can we can exclude adding dependency at runtime, in above scenario we are removing tomcat dependency and adding jetty as embedded server.
Similarly we can remove jetty dependency and we can add spring-boot-starter-undertow dependency if we want to deploy and run the application in undertow server.
Adding Servlet, Filter and Listeners to an application:
There are many ways to add servlet, Filter and Listeners to an applications.
- We can implement we can extend HTTPServlet, Filter and Listener interface and mark them Spring Beans, and the package will be available to Spring Component Scan.
- For servlets and filters we can use ServletRegistrationBean and FilterRegistrationBean Spring classes to register the servlets and filters. We can also provide init-param to servlet and filter. If we don’t specify the dispatching modes then by default it will be FORWARD, INCLUDE, REQUEST. We can also enable and disabled using setEnabled method by passing either true or false.
- @WebServlet, @WebFilter, and @WebListener annotated classes can be automatically registered with an embedded servlet container by annotating a @Configuration class with @ServletComponentScan and specifying the package(s) containing the components that you want to register. By default, @ServletComponentScan will scan from the package of the annotated class.
Assign Random Port to Embedded Server:
We can also assign port number based on availability of ports on Host Machine. If we set server.port=0 in application.properties then port number will be allocated during the run time.
org.springframework.util.SocketUtils.findAvailableTcpPort() is the method to assign the port number to embedded server during runtime.
Obtaining the Server Port:
After assigning the port number to server Spring Boot will raise EmbeddedServletContainerInitializedEvent event. We need to implement ApplicationListener of the type EmbeddedServletContainerInitializedEventto receive the event. ApplicationListener need to implement getSource() which will return EmbeddedServletContainer of the type, has method getPort() which will return the port number on which Embedded server is running.
Configuring SSL:SSL can be configured declaratively by setting the various server.ssl.* properties, typically in application.properties or application.yml file.
server.port=8443 server.ssl.key-store=classpath:keystore.jks server.ssl.key-store-password=secret server.ssl.key-password=another-secret
Spring Boot application either it will support HTTP or HTTPS, it does not support both connectors at the same time using application.properties file, but we can do the same using programmatically.
Configure Logging:
For Tomcat embedded server we can use prefix server.tomcat.* to configure Tomcat Server properties like max-connections, threads, log file etc… Some of mostly used properties are mentioned below:
server.tomcat.accesslog.enabled=true server.tomcat.accesslog.pattern=%t %a "%r" %s (%D ms) server.tomcat.accesslog.file-date-format=.yyyy-MM-dd server.tomcat.accesslog.rotate=true server.tomcat.max-connections=10 server.tomcat.max-threads=10 server.tomcat.max-http-post-size=2048
Similarly we can properties for Jetty embedded server properties using server.jetty.* prefix.
Adding Multiple Connectors in Embedded Server:
EmbeddedServletContainerCustomizer is the interface to customize the embedded server, where we can add connectors, error pages, providing proxy details etc…
Adding custom connectors, custom settings for each server by using below code.
@Component public class MyCustomizer implements EmbeddedServletContainerCustomizer{ @Override public void customize(ConfigurableEmbeddedServletContainer container) { if(TomcatEmbeddedServletContainerFactory.class.isAssignableFrom(container.getClass())) { log.info("in tomcat"); } if(JettyEmbeddedServletContainerFactory.class.isAssignableFrom(container.getClass())) { log.info("in jetty"); } } }
We can create a ServletContainerFactory for each embedded server, and add connectors to it.
@Component public class MyCustomizer implements EmbeddedServletContainerCustomizer{ @Override public void customize(ConfigurableEmbeddedServletContainer container) { if(TomcatEmbeddedServletContainerFactory.class.isAssignableFrom(container.getClass())) { log.info("in tomcat"); TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory = TomcatEmbeddedServletContainerFactory.class.cast(container); tomcatEmbeddedServletContainerFactory.addAdditionalTomcatConnectors(createTomcatSslConnector(),createTomcatAJPConnector()); } if(JettyEmbeddedServletContainerFactory.class.isAssignableFrom(container.getClass())) { log.info("in jetty"); JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory = JettyEmbeddedServletContainerFactory.class.cast(container); } } private Connector createTomcatSslConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); try { File keystore = new ClassPathResource("keystore").getFile(); File truststore = new ClassPathResource("keystore").getFile(); connector.setScheme("https"); connector.setSecure(true); connector.setPort(8443); protocol.setSSLEnabled(true); protocol.setKeystoreFile(keystore.getAbsolutePath()); protocol.setKeystorePass("keystorepass"); protocol.setTruststoreFile(truststore.getAbsolutePath()); protocol.setTruststorePass("keystorepass"); protocol.setKeyAlias("keyalias"); return connector; } catch (IOException ex) { throw new IllegalStateException("can't access keystore: [" + "keystore" + "] or truststore: [" + "keystore" + "]", ex); } } private Connector createTomcatAJPConnector() { Connector ajpConnector = new Connector("AJP/1.3"); ajpConnector.setPort(8081); ajpConnector.setSecure(false); ajpConnector.setAllowTrace(false); ajpConnector.setScheme("http"); return ajpConnector; } }
Enable HTTP response compression:
HTTP response Compression is supports by tomcat, jetty and undertow, it can be enabled using application.properties/application.yml file using server.compression.enabled=true property.
By default if the response size is greater than 2048 then only it will be enabled, but we can also customize the size using server.compression.min-response-size property, we can also limit the compression for MIME-Types using server.compression.mime-types property, by default text/html,text/xml,text/plain,text/css MIME-Types will be compressed.
Conclusion: Spring Boot by default comes with Tomcat as embedded server, but we can also customize on which we want to deploy our applications, can add multiple connectors, listeners based on embedded server, using application.properties file, we can customize the configuration without writing code.
In this article, you have learn about customized deployment for spring boot applications . If you have any question, ask to experts of Java web development company straightforward in comments. Do share your feedback for this post and tell other readers how your experience with this tutorial was.
Ethan Millar
Latest posts by Ethan Millar (see all)
- The Future Of Machine Learning And Data Science - September 26, 2017
- Easy Way to Add Help Section in CRM Entity Form - July 28, 2017
- Customized Deployment for Spring Boot Applications - June 2, 2017