3412 lines
130 KiB
Plaintext
3412 lines
130 KiB
Plaintext
[[howto]]
|
|
= '`How-to`' guides
|
|
|
|
[partintro]
|
|
--
|
|
This section provides answers to some common '`how do I do that...`' type of questions
|
|
that often arise when using Spring Boot. This is by no means an exhaustive list, but it
|
|
does cover quite a lot.
|
|
|
|
If you are having a specific problem that we don't cover here, you might want to check out
|
|
https://stackoverflow.com/tags/spring-boot[stackoverflow.com] to see if someone has
|
|
already provided an answer; this is also a great place to ask new questions (please use
|
|
the `spring-boot` tag).
|
|
|
|
We're also more than happy to extend this section; If you want to add a '`how-to`' you
|
|
can send us a {github-code}[pull request].
|
|
--
|
|
|
|
|
|
|
|
[[howto-spring-boot-application]]
|
|
== Spring Boot application
|
|
|
|
|
|
[[howto-failure-analyzer]]
|
|
=== Create your own FailureAnalyzer
|
|
{dc-spring-boot}/diagnostics/FailureAnalyzer.{dc-ext}[`FailureAnalyzer`] is a great way
|
|
to intercept an exception on startup and turn it into a human-readable message, wrapped
|
|
into a {dc-spring-boot}/diagnostics/FailureAnalysis.{dc-ext}[`FailureAnalysis`]. Spring
|
|
Boot provides such analyzer for application context related exceptions, JSR-303
|
|
validations and more. It is actually very easy to create your own.
|
|
|
|
`AbstractFailureAnalyzer` is a convenient extension of `FailureAnalyzer` that checks the
|
|
presence of a specified exception type in the exception to handle. You can extend from
|
|
that so that your implementation gets a chance to handle the exception only when it is
|
|
actually present. If for whatever reason you can't handle the exception, return `null`
|
|
to give another implementation a chance to handle the exception.
|
|
|
|
`FailureAnalyzer` implementations are to be registered in a `META-INF/spring.factories`:
|
|
the following registers `ProjectConstraintViolationFailureAnalyzer`:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
org.springframework.boot.diagnostics.FailureAnalyzer=\
|
|
com.example.ProjectConstraintViolationFailureAnalyzer
|
|
----
|
|
|
|
|
|
|
|
[[howto-troubleshoot-auto-configuration]]
|
|
=== Troubleshoot auto-configuration
|
|
The Spring Boot auto-configuration tries its best to '`do the right thing`', but
|
|
sometimes things fail and it can be hard to tell why.
|
|
|
|
There is a really useful `ConditionEvaluationReport` available in any Spring Boot
|
|
`ApplicationContext`. You will see it if you enable `DEBUG` logging output. If you use
|
|
the `spring-boot-actuator` there is also an `autoconfig` endpoint that renders the report
|
|
in JSON. Use that to debug the application and see what features have been added (and
|
|
which not) by Spring Boot at runtime.
|
|
|
|
Many more questions can be answered by looking at the source code and the Javadoc. Some
|
|
rules of thumb:
|
|
|
|
* Look for classes called `+*AutoConfiguration+` and read their sources, in particular the
|
|
`+@Conditional*+` annotations to find out what features they enable and when. Add
|
|
`--debug` to the command line or a System property `-Ddebug` to get a log on the
|
|
console of all the auto-configuration decisions that were made in your app. In a running
|
|
Actuator app look at the `autoconfig` endpoint ('`/autoconfig`' or the JMX equivalent) for
|
|
the same information.
|
|
* Look for classes that are `@ConfigurationProperties` (e.g.
|
|
{sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`])
|
|
and read from there the available external configuration options. The
|
|
`@ConfigurationProperties` has a `name` attribute which acts as a prefix to external
|
|
properties, thus `ServerProperties` has `prefix="server"` and its configuration properties
|
|
are `server.port`, `server.address` etc. In a running Actuator app look at the
|
|
`configprops` endpoint.
|
|
* Look for use of `RelaxedPropertyResolver` to pull configuration values explicitly out of the
|
|
`Environment`. It often is used with a prefix.
|
|
* Look for `@Value` annotations that bind directly to the `Environment`. This is less
|
|
flexible than the `RelaxedPropertyResolver` approach, but does allow some relaxed binding,
|
|
specifically for OS environment variables (so `CAPITALS_AND_UNDERSCORES` are synonyms
|
|
for `period.separated`).
|
|
* Look for `@ConditionalOnExpression` annotations that switch features on and off in
|
|
response to SpEL expressions, normally evaluated with placeholders resolved from the
|
|
`Environment`.
|
|
|
|
|
|
|
|
[[howto-customize-the-environment-or-application-context]]
|
|
=== Customize the Environment or ApplicationContext before it starts
|
|
A `SpringApplication` has `ApplicationListeners` and `ApplicationContextInitializers` that
|
|
are used to apply customizations to the context or environment. Spring Boot loads a number
|
|
of such customizations for use internally from `META-INF/spring.factories`. There is more
|
|
than one way to register additional ones:
|
|
|
|
* Programmatically per application by calling the `addListeners` and `addInitializers`
|
|
methods on `SpringApplication` before you run it.
|
|
* Declaratively per application by setting `context.initializer.classes` or
|
|
`context.listener.classes`.
|
|
* Declaratively for all applications by adding a `META-INF/spring.factories` and packaging
|
|
a jar file that the applications all use as a library.
|
|
|
|
The `SpringApplication` sends some special `ApplicationEvents` to the listeners (even
|
|
some before the context is created), and then registers the listeners for events published
|
|
by the `ApplicationContext` as well. See
|
|
_<<spring-boot-features.adoc#boot-features-application-events-and-listeners>>_ in the
|
|
'`Spring Boot features`' section for a complete list.
|
|
|
|
It is also possible to customize the `Environment` before the application context is
|
|
refreshed using `EnvironmentPostProcessor`. Each implementation should be registered in
|
|
`META-INF/spring.factories`:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor
|
|
----
|
|
|
|
|
|
|
|
[[howto-build-an-application-context-hierarchy]]
|
|
=== Build an ApplicationContext hierarchy (adding a parent or root context)
|
|
You can use the `ApplicationBuilder` class to create parent/child `ApplicationContext`
|
|
hierarchies. See _<<spring-boot-features.adoc#boot-features-fluent-builder-api>>_
|
|
in the '`Spring Boot features`' section for more information.
|
|
|
|
|
|
|
|
[[howto-create-a-non-web-application]]
|
|
=== Create a non-web application
|
|
Not all Spring applications have to be web applications (or web services). If you want to
|
|
execute some code in a `main` method, but also bootstrap a Spring application to set up
|
|
the infrastructure to use, then it's easy with the `SpringApplication` features of Spring
|
|
Boot. A `SpringApplication` changes its `ApplicationContext` class depending on whether it
|
|
thinks it needs a web application or not. The first thing you can do to help it is to just
|
|
leave the servlet API dependencies off the classpath. If you can't do that (e.g. you are
|
|
running 2 applications from the same code base) then you can explicitly call
|
|
`setWebEnvironment(false)` on your `SpringApplication` instance, or set the
|
|
`applicationContextClass` property (through the Java API or with external properties).
|
|
Application code that you want to run as your business logic can be implemented as a
|
|
`CommandLineRunner` and dropped into the context as a `@Bean` definition.
|
|
|
|
|
|
|
|
[[howto-properties-and-configuration]]
|
|
== Properties & configuration
|
|
|
|
|
|
|
|
[[howto-automatic-expansion]]
|
|
=== Automatically expand properties at build time
|
|
Rather than hardcoding some properties that are also specified in your project's build
|
|
configuration, you can automatically expand them using the existing build configuration
|
|
instead. This is possible in both Maven and Gradle.
|
|
|
|
|
|
|
|
[[howto-automatic-expansion-maven]]
|
|
==== Automatic property expansion using Maven
|
|
You can automatically expand properties from the Maven project using resource
|
|
filtering. If you use the `spring-boot-starter-parent` you can then refer to your
|
|
Maven '`project properties`' via `@..@` placeholders, e.g.
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.encoding=@project.build.sourceEncoding@
|
|
app.java.version=@java.version@
|
|
----
|
|
|
|
TIP: The `spring-boot:run` can add `src/main/resources` directly to the classpath
|
|
(for hot reloading purposes) if you enable the `addResources` flag. This circumvents
|
|
the resource filtering and this feature. You can use the `exec:java` goal instead
|
|
or customize the plugin's configuration, see the
|
|
{spring-boot-maven-plugin-site}/usage.html[plugin usage page] for more details.
|
|
|
|
If you don't use the starter parent, in your `pom.xml` you need (inside the `<build/>`
|
|
element):
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<resources>
|
|
<resource>
|
|
<directory>src/main/resources</directory>
|
|
<filtering>true</filtering>
|
|
</resource>
|
|
</resources>
|
|
----
|
|
|
|
and (inside `<plugins/>`):
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<plugin>
|
|
<groupId>org.apache.maven.plugins</groupId>
|
|
<artifactId>maven-resources-plugin</artifactId>
|
|
<version>2.7</version>
|
|
<configuration>
|
|
<delimiters>
|
|
<delimiter>@</delimiter>
|
|
</delimiters>
|
|
<useDefaultDelimiters>false</useDefaultDelimiters>
|
|
</configuration>
|
|
</plugin>
|
|
----
|
|
|
|
NOTE: The `useDefaultDelimiters` property is important if you are using standard Spring
|
|
placeholders in your configuration (e.g. `${foo}`). These may be expanded by the build if
|
|
that property is not set to `false`.
|
|
|
|
|
|
|
|
[[howto-automatic-expansion-gradle]]
|
|
==== Automatic property expansion using Gradle
|
|
You can automatically expand properties from the Gradle project by configuring the
|
|
Java plugin's `processResources` task to do so:
|
|
|
|
[source,groovy,indent=0]
|
|
----
|
|
processResources {
|
|
expand(project.properties)
|
|
}
|
|
----
|
|
|
|
You can then refer to your Gradle project's properties via placeholders, e.g.
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.name=${name}
|
|
app.description=${description}
|
|
----
|
|
|
|
NOTE: Gradle's `expand` method uses Groovy's `SimpleTemplateEngine` which transforms
|
|
`${..}` tokens. The `${..}` style conflicts with Spring's own property placeholder
|
|
mechanism. To use Spring property placeholders together with automatic expansion
|
|
the Spring property placeholders need to be escaped like `\${..}`.
|
|
|
|
|
|
|
|
|
|
[[howto-externalize-configuration]]
|
|
=== Externalize the configuration of SpringApplication
|
|
A `SpringApplication` has bean properties (mainly setters) so you can use its Java API as
|
|
you create the application to modify its behavior. Or you can externalize the
|
|
configuration using properties in `+spring.main.*+`. E.g. in `application.properties` you
|
|
might have.
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.main.web-environment=false
|
|
spring.main.banner-mode=off
|
|
----
|
|
|
|
and then the Spring Boot banner will not be printed on startup, and the application will
|
|
not be a web application.
|
|
|
|
NOTE: The example above also demonstrates how flexible binding allows the use of
|
|
underscores (`_`) as well as dashes (`-`) in property names.
|
|
|
|
Properties defined in external configuration overrides the values specified via the Java
|
|
API with the notable exception of the sources used to create the `ApplicationContext`. Let's
|
|
consider this application
|
|
|
|
[source,java,indent=0]
|
|
----
|
|
new SpringApplicationBuilder()
|
|
.bannerMode(Banner.Mode.OFF)
|
|
.sources(demo.MyApp.class)
|
|
.run(args);
|
|
----
|
|
|
|
used with the following configuration:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.main.sources=com.acme.Config,com.acme.ExtraConfig
|
|
spring.main.banner-mode=console
|
|
----
|
|
|
|
The actual application will _now_ show the banner (as overridden by configuration) and use
|
|
three sources for the `ApplicationContext` (in that order): `demo.MyApp`, `com.acme.Config`,
|
|
`com.acme.ExtraConfig`.
|
|
|
|
|
|
|
|
[[howto-change-the-location-of-external-properties]]
|
|
=== Change the location of external properties of an application
|
|
By default properties from different sources are added to the Spring `Environment` in a
|
|
defined order (see _<<spring-boot-features.adoc#boot-features-external-config>>_ in
|
|
the '`Spring Boot features`' section for the exact order).
|
|
|
|
A nice way to augment and modify this is to add `@PropertySource` annotations to your
|
|
application sources. Classes passed to the `SpringApplication` static convenience
|
|
methods, and those added using `setSources()` are inspected to see if they have
|
|
`@PropertySources`, and if they do, those properties are added to the `Environment` early
|
|
enough to be used in all phases of the `ApplicationContext` lifecycle. Properties added
|
|
in this way have lower
|
|
priority than any added using the default locations (e.g. `application.properties`), system properties, environment variables or the command line.
|
|
|
|
You can also provide System properties (or environment variables) to change the behavior:
|
|
|
|
* `spring.config.name` (`SPRING_CONFIG_NAME`), defaults to `application` as the root of
|
|
the file name.
|
|
* `spring.config.location` (`SPRING_CONFIG_LOCATION`) is the file to load (e.g. a classpath
|
|
resource or a URL). A separate `Environment` property source is set up for this document
|
|
and it can be overridden by system properties, environment variables or the
|
|
command line.
|
|
|
|
No matter what you set in the environment, Spring Boot will always load
|
|
`application.properties` as described above. If YAML is used then files with the '`.yml`'
|
|
extension are also added to the list by default.
|
|
|
|
Spring Boot logs the configuration files that are loaded at `DEBUG` level and the
|
|
candidates it has not found at `TRACE` level.
|
|
|
|
See {sc-spring-boot}/context/config/ConfigFileApplicationListener.{sc-ext}[`ConfigFileApplicationListener`]
|
|
for more detail.
|
|
|
|
|
|
|
|
[[howto-use-short-command-line-arguments]]
|
|
=== Use '`short`' command line arguments
|
|
Some people like to use (for example) `--port=9000` instead of `--server.port=9000` to
|
|
set configuration properties on the command line. You can easily enable this by using
|
|
placeholders in `application.properties`, e.g.
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
server.port=${port:8080}
|
|
----
|
|
|
|
TIP: If you are inheriting from the `spring-boot-starter-parent` POM, the default filter
|
|
token of the `maven-resources-plugins` has been changed from `+${*}+` to `@` (i.e.
|
|
`@maven.token@` instead of `${maven.token}`) to prevent conflicts with Spring-style
|
|
placeholders. If you have enabled maven filtering for the `application.properties`
|
|
directly, you may want to also change the default filter token to use
|
|
https://maven.apache.org/plugins/maven-resources-plugin/resources-mojo.html#delimiters[other delimiters].
|
|
|
|
NOTE: In this specific case the port binding will work in a PaaS environment like Heroku
|
|
and Cloud Foundry, since in those two platforms the `PORT` environment variable is set
|
|
automatically and Spring can bind to capitalized synonyms for `Environment` properties.
|
|
|
|
|
|
|
|
[[howto-use-yaml-for-external-properties]]
|
|
=== Use YAML for external properties
|
|
YAML is a superset of JSON and as such is a very convenient syntax for storing external
|
|
properties in a hierarchical format. E.g.
|
|
|
|
[source,yaml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring:
|
|
application:
|
|
name: cruncher
|
|
datasource:
|
|
driverClassName: com.mysql.jdbc.Driver
|
|
url: jdbc:mysql://localhost/test
|
|
server:
|
|
port: 9000
|
|
----
|
|
|
|
Create a file called `application.yml` and stick it in the root of your classpath, and
|
|
also add `snakeyaml` to your dependencies (Maven coordinates `org.yaml:snakeyaml`, already
|
|
included if you use the `spring-boot-starter`). A YAML file is parsed to a Java
|
|
`Map<String,Object>` (like a JSON object), and Spring Boot flattens the map so that it
|
|
is 1-level deep and has period-separated keys, a lot like people are used to with
|
|
`Properties` files in Java.
|
|
|
|
The example YAML above corresponds to an `application.properties` file
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.application.name=cruncher
|
|
spring.datasource.driverClassName=com.mysql.jdbc.Driver
|
|
spring.datasource.url=jdbc:mysql://localhost/test
|
|
server.port=9000
|
|
----
|
|
|
|
See _<<spring-boot-features.adoc#boot-features-external-config-yaml>>_ in
|
|
the '`Spring Boot features`' section for more information
|
|
about YAML.
|
|
|
|
[[howto-set-active-spring-profiles]]
|
|
=== Set the active Spring profiles
|
|
The Spring `Environment` has an API for this, but normally you would set a System property
|
|
(`spring.profiles.active`) or an OS environment variable (`SPRING_PROFILES_ACTIVE`). E.g.
|
|
launch your application with a `-D` argument (remember to put it before the main class
|
|
or jar archive):
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
$ java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar
|
|
----
|
|
|
|
In Spring Boot you can also set the active profile in `application.properties`, e.g.
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.profiles.active=production
|
|
----
|
|
|
|
A value set this way is replaced by the System property or environment variable setting,
|
|
but not by the `SpringApplicationBuilder.profiles()` method. Thus the latter Java API can
|
|
be used to augment the profiles without changing the defaults.
|
|
|
|
See _<<spring-boot-features.adoc#boot-features-profiles>>_ in
|
|
the '`Spring Boot features`' section for more information.
|
|
|
|
|
|
|
|
[[howto-change-configuration-depending-on-the-environment]]
|
|
=== Change configuration depending on the environment
|
|
A YAML file is actually a sequence of documents separated by `---` lines, and each
|
|
document is parsed separately to a flattened map.
|
|
|
|
If a YAML document contains a `spring.profiles` key, then the profiles value
|
|
(comma-separated list of profiles) is fed into the Spring
|
|
`Environment.acceptsProfiles()` and if any of those profiles is active that document is
|
|
included in the final merge (otherwise not).
|
|
|
|
Example:
|
|
|
|
[source,yaml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
server:
|
|
port: 9000
|
|
---
|
|
|
|
spring:
|
|
profiles: development
|
|
server:
|
|
port: 9001
|
|
|
|
---
|
|
|
|
spring:
|
|
profiles: production
|
|
server:
|
|
port: 0
|
|
----
|
|
|
|
In this example the default port is 9000, but if the Spring profile '`development`' is
|
|
active then the port is 9001, and if '`production`' is active then it is 0.
|
|
|
|
The YAML documents are merged in the order they are encountered (so later values override
|
|
earlier ones).
|
|
|
|
To do the same thing with properties files you can use `application-${profile}.properties`
|
|
to specify profile-specific values.
|
|
|
|
|
|
|
|
[[howto-discover-build-in-options-for-external-properties]]
|
|
=== Discover built-in options for external properties
|
|
Spring Boot binds external properties from `application.properties` (or `.yml`) (and
|
|
other places) into an application at runtime. There is not (and technically cannot be)
|
|
an exhaustive list of all supported properties in a single location because contributions
|
|
can come from additional jar files on your classpath.
|
|
|
|
A running application with the Actuator features has a `configprops` endpoint that shows
|
|
all the bound and bindable properties available through `@ConfigurationProperties`.
|
|
|
|
The appendix includes an <<appendix-application-properties#common-application-properties,
|
|
`application.properties`>> example with a list of the most common properties supported by
|
|
Spring Boot. The definitive list comes from searching the source code for
|
|
`@ConfigurationProperties` and `@Value` annotations, as well as the occasional use of
|
|
`RelaxedPropertyResolver`.
|
|
|
|
|
|
|
|
[[howto-embedded-servlet-containers]]
|
|
== Embedded servlet containers
|
|
|
|
|
|
|
|
[[howto-add-a-servlet-filter-or-listener]]
|
|
=== Add a Servlet, Filter or Listener to an application
|
|
There are two ways to add `Servlet`, `Filter`, `ServletContextListener` and the other
|
|
listeners supported by the Servlet spec to your application. You can either provide
|
|
Spring beans for them, or enable scanning for Servlet components.
|
|
|
|
|
|
|
|
[[howto-add-a-servlet-filter-or-listener-as-spring-bean]]
|
|
==== Add a Servlet, Filter or Listener using a Spring bean
|
|
To add a `Servlet`, `Filter`, or Servlet `*Listener` provide a `@Bean` definition for it.
|
|
This can be very useful when you want to inject configuration or dependencies. However,
|
|
you must be very careful that they don't cause eager initialization of too many other
|
|
beans because they have to be installed in the container very early in the application
|
|
lifecycle (e.g. it's not a good idea to have them depend on your `DataSource` or JPA
|
|
configuration). You can work around restrictions like that by initializing them lazily
|
|
when first used instead of on initialization.
|
|
|
|
In the case of `Filters` and `Servlets` you can also add mappings and init parameters by
|
|
adding a `FilterRegistrationBean` or `ServletRegistrationBean` instead of or as well as
|
|
the underlying component.
|
|
|
|
[NOTE]
|
|
====
|
|
If no `dispatcherType` is specified on a filter registration, it will match
|
|
`FORWARD`,`INCLUDE` and `REQUEST`. If async has been enabled, it will match `ASYNC` as
|
|
well.
|
|
|
|
If you are migrating a filter that has no `dispatcher` element in `web.xml` you will
|
|
need to specify a `dispatcherType` yourself:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean
|
|
public FilterRegistrationBean myFilterRegistration() {
|
|
FilterRegistrationBean registration = new FilterRegistrationBean();
|
|
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
|
....
|
|
|
|
return registration;
|
|
}
|
|
----
|
|
====
|
|
|
|
|
|
[[howto-disable-registration-of-a-servlet-or-filter]]
|
|
===== Disable registration of a Servlet or Filter
|
|
As <<howto-add-a-servlet-filter-or-listener-as-spring-bean,described above>> any `Servlet`
|
|
or `Filter` beans will be registered with the servlet container automatically. To disable
|
|
registration of a particular `Filter` or `Servlet` bean create a registration bean for it
|
|
and mark it as disabled. For example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean
|
|
public FilterRegistrationBean registration(MyFilter filter) {
|
|
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
|
|
registration.setEnabled(false);
|
|
return registration;
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-add-a-servlet-filter-or-listener-using-scanning]]
|
|
==== Add Servlets, Filters, and Listeners using classpath scanning
|
|
`@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.
|
|
|
|
|
|
|
|
[[howto-change-the-http-port]]
|
|
=== Change the HTTP port
|
|
In a standalone application the main HTTP port defaults to `8080`, but can be set with
|
|
`server.port` (e.g. in `application.properties` or as a System property). Thanks to
|
|
relaxed binding of `Environment` values you can also use `SERVER_PORT` (e.g. as an OS
|
|
environment variable).
|
|
|
|
To switch off the HTTP endpoints completely, but still create a `WebApplicationContext`,
|
|
use `server.port=-1` (this is sometimes useful for testing).
|
|
|
|
For more details look at _<<spring-boot-features.adoc#boot-features-customizing-embedded-containers>>_
|
|
in the '`Spring Boot features`' section, or the
|
|
{sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`] source
|
|
code.
|
|
|
|
|
|
|
|
[[howto-user-a-random-unassigned-http-port]]
|
|
=== Use a random unassigned HTTP port
|
|
To scan for a free port (using OS natives to prevent clashes) use `server.port=0`.
|
|
|
|
|
|
|
|
[[howto-discover-the-http-port-at-runtime]]
|
|
=== Discover the HTTP port at runtime
|
|
You can access the port the server is running on from log output or from the
|
|
`EmbeddedWebApplicationContext` via its `EmbeddedServletContainer`. The best way to get
|
|
that and be sure that it has initialized is to add a `@Bean` of type
|
|
`ApplicationListener<EmbeddedServletContainerInitializedEvent>` and pull the container
|
|
out of the event when it is published.
|
|
|
|
Tests that use `@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)` can
|
|
also inject the actual port into a field using the `@LocalServerPort` annotation. For
|
|
example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@RunWith(SpringJUnit4ClassRunner.class)
|
|
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
|
|
public class MyWebIntegrationTests {
|
|
|
|
@Autowired
|
|
EmbeddedWebApplicationContext server;
|
|
|
|
@LocalServerPort
|
|
int port;
|
|
|
|
// ...
|
|
|
|
}
|
|
----
|
|
|
|
[NOTE]
|
|
====
|
|
`@LocalServerPort` is a meta-annotation for `@Value("${local.server.port}")`. Don't try
|
|
to inject the port in a regular application. As we just saw, the value is only set once
|
|
the container has initialized; contrary to a test, application code callbacks are
|
|
processed early (i.e. before the value is actually available).
|
|
====
|
|
|
|
|
|
|
|
[[howto-configure-ssl]]
|
|
=== Configure SSL
|
|
SSL can be configured declaratively by setting the various `+server.ssl.*+` properties,
|
|
typically in `application.properties` or `application.yml`. For example:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
server.port=8443
|
|
server.ssl.key-store=classpath:keystore.jks
|
|
server.ssl.key-store-password=secret
|
|
server.ssl.key-password=another-secret
|
|
----
|
|
|
|
See {sc-spring-boot}/context/embedded/Ssl.{sc-ext}[`Ssl`] for details of all of the
|
|
supported properties.
|
|
|
|
Using configuration like the example above means the application will no longer support
|
|
plain HTTP connector at port 8080. Spring Boot doesn't support the configuration of both
|
|
an HTTP connector and an HTTPS connector via `application.properties`. If you want to
|
|
have both then you'll need to configure one of them programmatically. It's recommended
|
|
to use `application.properties` to configure HTTPS as the HTTP connector is the easier of
|
|
the two to configure programmatically. See the
|
|
{github-code}/spring-boot-samples/spring-boot-sample-tomcat-multi-connectors[`spring-boot-sample-tomcat-multi-connectors`]
|
|
sample project for an example.
|
|
|
|
|
|
|
|
[[howto-configure-accesslogs]]
|
|
=== Configure Access Logging
|
|
Access logs can be configured for Tomcat and Undertow via their respective namespaces.
|
|
|
|
For instance, the following logs access on Tomcat with a
|
|
https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Access_Logging[custom pattern].
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
server.tomcat.basedir=my-tomcat
|
|
server.tomcat.accesslog.enabled=true
|
|
server.tomcat.accesslog.pattern=%t %a "%r" %s (%D ms)
|
|
----
|
|
|
|
NOTE: The default location for logs is a `logs` directory relative to the tomcat base dir
|
|
and said directory is a temp directory by default so you may want to fix Tomcat's base
|
|
directory or use an absolute path for the logs. In the example above, the logs will
|
|
be available in `my-tomcat/logs` relative to the working directory of the application.
|
|
|
|
Access logging for undertow can be configured in a similar fashion
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
server.undertow.accesslog.enabled=true
|
|
server.undertow.accesslog.pattern=%t %a "%r" %s (%D ms)
|
|
----
|
|
|
|
Logs are stored in a `logs` directory relative to the working directory of the
|
|
application. This can be customized via `server.undertow.accesslog.directory`.
|
|
|
|
|
|
|
|
[[howto-use-behind-a-proxy-server]]
|
|
[[howto-use-tomcat-behind-a-proxy-server]]
|
|
=== Use behind a front-end proxy server
|
|
Your application might need to send `302` redirects or render content with absolute links
|
|
back to itself. When running behind a proxy, the caller wants a link to the proxy, and not
|
|
to the physical address of the machine hosting your app. Typically such situations are
|
|
handled via a contract with the proxy, which will add headers to tell the back end how to
|
|
construct links to itself.
|
|
|
|
If the proxy adds conventional `X-Forwarded-For` and `X-Forwarded-Proto` headers (most do
|
|
this out of the box) the absolute links should be rendered correctly as long as
|
|
`server.use-forward-headers` is set to `true` in your `application.properties`.
|
|
|
|
NOTE: If your application is running in Cloud Foundry or Heroku the
|
|
`server.use-forward-headers` property will default to `true` if not specified. In all
|
|
other instances it defaults to `false`.
|
|
|
|
|
|
|
|
[[howto-customize-tomcat-behind-a-proxy-server]]
|
|
==== Customize Tomcat's proxy configuration
|
|
If you are using Tomcat you can additionally configure the names of the headers used to
|
|
carry "`forwarded`" information:
|
|
|
|
[indent=0]
|
|
----
|
|
server.tomcat.remote-ip-header=x-your-remote-ip-header
|
|
server.tomcat.protocol-header=x-your-protocol-header
|
|
----
|
|
|
|
Tomcat is also configured with a default regular expression that matches internal
|
|
proxies that are to be trusted. By default, IP addresses in `10/8`, `192.168/16`,
|
|
`169.254/16` and `127/8` are trusted. You can customize the valve's configuration by
|
|
adding an entry to `application.properties`, e.g.
|
|
|
|
[indent=0]
|
|
----
|
|
server.tomcat.internal-proxies=192\\.168\\.\\d{1,3}\\.\\d{1,3}
|
|
----
|
|
|
|
NOTE: The double backslashes are only required when you're using a properties file for
|
|
configuration. If you are using YAML, single backslashes are sufficient and a value
|
|
that's equivalent to the one shown above would be `192\.168\.\d{1,3}\.\d{1,3}`.
|
|
|
|
NOTE: You can trust all proxies by setting the `internal-proxies` to empty (but don't do
|
|
this in production).
|
|
|
|
You can take complete control of the configuration of Tomcat's `RemoteIpValve` by
|
|
switching the automatic one off (i.e. set `server.use-forward-headers=false`) and adding
|
|
a new valve instance in a `TomcatEmbeddedServletContainerFactory` bean.
|
|
|
|
|
|
|
|
[[howto-configure-tomcat]]
|
|
=== Configure Tomcat
|
|
Generally you can follow the advice from
|
|
_<<howto-discover-build-in-options-for-external-properties>>_ about
|
|
`@ConfigurationProperties` (`ServerProperties` is the main one here), but also look at
|
|
`EmbeddedServletContainerCustomizer` and various Tomcat-specific `+*Customizers+` that you
|
|
can add in one of those. The Tomcat APIs are quite rich so once you have access to the
|
|
`TomcatEmbeddedServletContainerFactory` you can modify it in a number of ways. Or the
|
|
nuclear option is to add your own `TomcatEmbeddedServletContainerFactory`.
|
|
|
|
|
|
|
|
[[howto-enable-multiple-connectors-in-tomcat]]
|
|
=== Enable Multiple Connectors with Tomcat
|
|
Add a `org.apache.catalina.connector.Connector` to the
|
|
`TomcatEmbeddedServletContainerFactory` which can allow multiple connectors, e.g. HTTP and
|
|
HTTPS connector:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean
|
|
public EmbeddedServletContainerFactory servletContainer() {
|
|
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
|
|
tomcat.addAdditionalTomcatConnectors(createSslConnector());
|
|
return tomcat;
|
|
}
|
|
|
|
private Connector createSslConnector() {
|
|
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("changeit");
|
|
protocol.setTruststoreFile(truststore.getAbsolutePath());
|
|
protocol.setTruststorePass("changeit");
|
|
protocol.setKeyAlias("apitester");
|
|
return connector;
|
|
}
|
|
catch (IOException ex) {
|
|
throw new IllegalStateException("can't access keystore: [" + "keystore"
|
|
+ "] or truststore: [" + "keystore" + "]", ex);
|
|
}
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-use-tomcat-legacycookieprocessor]]
|
|
=== Use Tomcat's LegacyCookieProcessor
|
|
The embedded Tomcat used by Spring Boot does not support "Version 0" of the Cookie
|
|
format out of the box, and you may see the following error:
|
|
|
|
[indent=0]
|
|
----
|
|
java.lang.IllegalArgumentException: An invalid character [32] was present in the Cookie value
|
|
----
|
|
|
|
If at all possible, you should consider updating your code to only store values
|
|
compliant with later Cookie specifications. If, however, you're unable to change the
|
|
way that cookies are written, you can instead configure Tomcat to use a
|
|
`LegacyCookieProcessor`. To switch to the `LegacyCookieProcessor` use an
|
|
`EmbeddedServletContainerCustomizer` bean that adds a `TomcatContextCustomizer`:
|
|
|
|
[source,java,indent=0]
|
|
----
|
|
include::{code-examples}/context/embedded/TomcatLegacyCookieProcessorExample.java[tag=customizer]
|
|
----
|
|
|
|
|
|
|
|
[[howto-use-jetty-instead-of-tomcat]]
|
|
=== Use Jetty instead of Tomcat
|
|
The Spring Boot starters (`spring-boot-starter-web` in particular) use Tomcat as an
|
|
embedded container by default. You need to exclude those dependencies and include the
|
|
Jetty one instead. Spring Boot provides Tomcat and Jetty dependencies bundled together
|
|
as separate starters to help make this process as easy as possible.
|
|
|
|
Example in Maven:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
<exclusions>
|
|
<exclusion>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
|
</exclusion>
|
|
</exclusions>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-jetty</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
Example in Gradle:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
configurations {
|
|
compile.exclude module: "spring-boot-starter-tomcat"
|
|
}
|
|
|
|
dependencies {
|
|
compile("org.springframework.boot:spring-boot-starter-web:{spring-boot-version}")
|
|
compile("org.springframework.boot:spring-boot-starter-jetty:{spring-boot-version}")
|
|
// ...
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-configure-jetty]]
|
|
=== Configure Jetty
|
|
Generally you can follow the advice from
|
|
_<<howto-discover-build-in-options-for-external-properties>>_ about
|
|
`@ConfigurationProperties` (`ServerProperties` is the main one here), but also look at
|
|
`EmbeddedServletContainerCustomizer`. The Jetty APIs are quite rich so once you have
|
|
access to the `JettyEmbeddedServletContainerFactory` you can modify it in a number
|
|
of ways. Or the nuclear option is to add your own `JettyEmbeddedServletContainerFactory`.
|
|
|
|
|
|
|
|
[[howto-use-undertow-instead-of-tomcat]]
|
|
=== Use Undertow instead of Tomcat
|
|
Using Undertow instead of Tomcat is very similar to <<howto-use-jetty-instead-of-tomcat,
|
|
using Jetty instead of Tomcat>>. You need to exclude the Tomcat dependencies and include
|
|
the Undertow starter instead.
|
|
|
|
Example in Maven:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
<exclusions>
|
|
<exclusion>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
|
</exclusion>
|
|
</exclusions>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-undertow</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
Example in Gradle:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
configurations {
|
|
compile.exclude module: "spring-boot-starter-tomcat"
|
|
}
|
|
|
|
dependencies {
|
|
compile("org.springframework.boot:spring-boot-starter-web:{spring-boot-version}")
|
|
compile("org.springframework.boot:spring-boot-starter-undertow:{spring-boot-version}")
|
|
// ...
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-configure-undertow]]
|
|
=== Configure Undertow
|
|
Generally you can follow the advice from
|
|
_<<howto-discover-build-in-options-for-external-properties>>_ about
|
|
`@ConfigurationProperties` (`ServerProperties` and `ServerProperties.Undertow` are the
|
|
main ones here), but also look at
|
|
`EmbeddedServletContainerCustomizer`. Once you have access to the
|
|
`UndertowEmbeddedServletContainerFactory` you can use an `UndertowBuilderCustomizer` to
|
|
modify Undertow's configuration to meet your needs. Or the nuclear option is to add your
|
|
own `UndertowEmbeddedServletContainerFactory`.
|
|
|
|
|
|
|
|
[[howto-enable-multiple-listeners-in-undertow]]
|
|
=== Enable Multiple Listeners with Undertow
|
|
Add an `UndertowBuilderCustomizer` to the `UndertowEmbeddedServletContainerFactory` and
|
|
add a listener to the `Builder`:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean
|
|
public UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() {
|
|
UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
|
|
factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
|
|
|
|
@Override
|
|
public void customize(Builder builder) {
|
|
builder.addHttpListener(8080, "0.0.0.0");
|
|
}
|
|
|
|
});
|
|
return factory;
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-use-tomcat-7]]
|
|
=== Use Tomcat 7.x or 8.0
|
|
Tomcat 7 & 8.0 work with Spring Boot, but the default is to use Tomcat 8.5. If you cannot
|
|
use Tomcat 8.5 (for example, because you are using Java 1.6) you will need to change your
|
|
classpath to reference a different version.
|
|
|
|
|
|
|
|
[[howto-use-tomcat-7-maven]]
|
|
==== Use Tomcat 7.x or 8.0 with Maven
|
|
If you are using the starters and parent you can change the Tomcat version property
|
|
and additionally import `tomcat-juli`. E.g. for a simple webapp or service:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<properties>
|
|
<tomcat.version>7.0.59</tomcat.version>
|
|
</properties>
|
|
<dependencies>
|
|
...
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.apache.tomcat</groupId>
|
|
<artifactId>tomcat-juli</artifactId>
|
|
<version>${tomcat.version}</version>
|
|
</dependency>
|
|
...
|
|
</dependencies>
|
|
----
|
|
|
|
|
|
|
|
==== Use Tomcat 7.x or 8.0 with Gradle
|
|
[[howto-use-tomcat-7-gradle]]
|
|
With Gradle, you can change the Tomcat version by setting the `tomcat.version` property
|
|
and then additionally include `tomcat-juli`:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
ext['tomcat.version'] = '7.0.59'
|
|
dependencies {
|
|
compile 'org.springframework.boot:spring-boot-starter-web'
|
|
compile group:'org.apache.tomcat', name:'tomcat-juli', version:property('tomcat.version')
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-use-jetty-9.2]]
|
|
=== Use Jetty 9.2
|
|
Jetty 9.2 works with Spring Boot, but the default is to use Jetty 9.3. If you cannot use
|
|
Jetty 9.3 (for example, because you are using Java 7) you will need to change your
|
|
classpath to reference Jetty 9.2.
|
|
|
|
|
|
|
|
[[howto-use-jetty-9.2-maven]]
|
|
==== Use Jetty 9.2 with Maven
|
|
|
|
If you are using the starters and parent you can just add the Jetty starter and override
|
|
the `jetty.version` property:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<properties>
|
|
<jetty.version>9.2.17.v20160517</jetty.version>
|
|
</properties>
|
|
<dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
<exclusions>
|
|
<exclusion>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
|
</exclusion>
|
|
</exclusions>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-jetty</artifactId>
|
|
</dependency>
|
|
</dependencies>
|
|
----
|
|
|
|
|
|
|
|
[[howto-use-jetty-9.2-gradle]]
|
|
==== Use Jetty 9.2 with Gradle
|
|
|
|
You can set the `jetty.version` property. For example, for a simple webapp or service:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
ext['jetty.version'] = '9.2.17.v20160517'
|
|
dependencies {
|
|
compile ('org.springframework.boot:spring-boot-starter-web') {
|
|
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
|
|
}
|
|
compile ('org.springframework.boot:spring-boot-starter-jetty')
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-use-jetty-8]]
|
|
=== Use Jetty 8
|
|
Jetty 8 works with Spring Boot, but the default is to use Jetty 9.3. If you cannot use
|
|
Jetty 9.3 (for example, because you are using Java 1.6) you will need to change your
|
|
classpath to reference Jetty 8. You will also need to exclude Jetty's WebSocket-related
|
|
dependencies.
|
|
|
|
|
|
|
|
[[howto-use-jetty-8-maven]]
|
|
==== Use Jetty 8 with Maven
|
|
|
|
If you are using the starters and parent you can just add the Jetty starter with
|
|
the required WebSocket exclusion and change the version properties, e.g. for a simple
|
|
webapp or service:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<properties>
|
|
<jetty.version>8.1.15.v20140411</jetty.version>
|
|
<jetty-jsp.version>2.2.0.v201112011158</jetty-jsp.version>
|
|
</properties>
|
|
<dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
<exclusions>
|
|
<exclusion>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
|
</exclusion>
|
|
</exclusions>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-jetty</artifactId>
|
|
<exclusions>
|
|
<exclusion>
|
|
<groupId>org.eclipse.jetty.websocket</groupId>
|
|
<artifactId>*</artifactId>
|
|
</exclusion>
|
|
</exclusions>
|
|
</dependency>
|
|
</dependencies>
|
|
----
|
|
|
|
|
|
|
|
[[howto-use-jetty-8-gradle]]
|
|
==== Use Jetty 8 with Gradle
|
|
|
|
You can set the `jetty.version` property and exclude the WebSocket dependency, e.g. for a
|
|
simple webapp or service:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
ext['jetty.version'] = '8.1.15.v20140411'
|
|
dependencies {
|
|
compile ('org.springframework.boot:spring-boot-starter-web') {
|
|
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
|
|
}
|
|
compile ('org.springframework.boot:spring-boot-starter-jetty') {
|
|
exclude group: 'org.eclipse.jetty.websocket'
|
|
}
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-create-websocket-endpoints-using-serverendpoint]]
|
|
=== Create WebSocket endpoints using @ServerEndpoint
|
|
If you want to use `@ServerEndpoint` in a Spring Boot application that used an embedded
|
|
container, you must declare a single `ServerEndpointExporter` `@Bean`:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean
|
|
public ServerEndpointExporter serverEndpointExporter() {
|
|
return new ServerEndpointExporter();
|
|
}
|
|
----
|
|
|
|
This bean will register any `@ServerEndpoint` annotated beans with the underlying
|
|
WebSocket container. When deployed to a standalone servlet container this role is
|
|
performed by a servlet container initializer and the `ServerEndpointExporter` bean is
|
|
not required.
|
|
|
|
|
|
|
|
[[how-to-enable-http-response-compression]]
|
|
=== Enable HTTP response compression
|
|
HTTP response compression is supported by Jetty, Tomcat, and Undertow. It can be enabled
|
|
via `application.properties`:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
server.compression.enabled=true
|
|
----
|
|
|
|
By default, responses must be at least 2048 bytes in length for compression to be
|
|
performed. This can be configured using the `server.compression.min-response-size`
|
|
property.
|
|
|
|
By default, responses will only be compressed if their content type is one of the
|
|
following:
|
|
|
|
- `text/html`
|
|
- `text/xml`
|
|
- `text/plain`
|
|
- `text/css`
|
|
|
|
This can be configured using the `server.compression.mime-types` property.
|
|
|
|
|
|
|
|
[[howto-spring-mvc]]
|
|
== Spring MVC
|
|
|
|
|
|
|
|
[[howto-write-a-json-rest-service]]
|
|
=== Write a JSON REST service
|
|
Any Spring `@RestController` in a Spring Boot application should render JSON response by
|
|
default as long as Jackson2 is on the classpath. For example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@RestController
|
|
public class MyController {
|
|
|
|
@RequestMapping("/thing")
|
|
public MyThing thing() {
|
|
return new MyThing();
|
|
}
|
|
|
|
}
|
|
----
|
|
|
|
As long as `MyThing` can be serialized by Jackson2 (e.g. a normal POJO or Groovy object)
|
|
then `http://localhost:8080/thing` will serve a JSON representation of it by default.
|
|
Sometimes in a browser you might see XML responses because browsers tend to send accept
|
|
headers that prefer XML.
|
|
|
|
|
|
|
|
[[howto-write-an-xml-rest-service]]
|
|
=== Write an XML REST service
|
|
If you have the Jackson XML extension (`jackson-dataformat-xml`) on the classpath, it will
|
|
be used to render XML responses and the very same example as we used for JSON would work.
|
|
To use it, add the following dependency to your project:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependency>
|
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
|
<artifactId>jackson-dataformat-xml</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
You may also want to add a dependency on Woodstox. It's faster than the default StAX
|
|
implementation provided by the JDK and also adds pretty print support and improved
|
|
namespace handling:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependency>
|
|
<groupId>org.codehaus.woodstox</groupId>
|
|
<artifactId>woodstox-core-asl</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
If Jackson's XML extension is not available, JAXB (provided by default in the JDK) will
|
|
be used, with the additional requirement to have `MyThing` annotated as
|
|
`@XmlRootElement`:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@XmlRootElement
|
|
public class MyThing {
|
|
private String name;
|
|
// .. getters and setters
|
|
}
|
|
----
|
|
|
|
To get the server to render XML instead of JSON you might have to send an
|
|
`Accept: text/xml` header (or use a browser).
|
|
|
|
|
|
|
|
[[howto-customize-the-jackson-objectmapper]]
|
|
=== Customize the Jackson ObjectMapper
|
|
Spring MVC (client and server side) uses `HttpMessageConverters` to negotiate content
|
|
conversion in an HTTP exchange. If Jackson is on the classpath you already get the
|
|
default converter(s) provided by `Jackson2ObjectMapperBuilder`, an instance of which
|
|
is auto-configured for you.
|
|
|
|
The `ObjectMapper` (or `XmlMapper` for Jackson XML converter) instance created by default
|
|
has the following customized properties:
|
|
|
|
* `MapperFeature.DEFAULT_VIEW_INCLUSION` is disabled
|
|
* `DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES` is disabled
|
|
|
|
Spring Boot has also some features to make it easier to customize this behavior.
|
|
|
|
You can configure the `ObjectMapper` and `XmlMapper` instances using the environment.
|
|
Jackson provides an extensive suite of simple on/off features that can be used to
|
|
configure various aspects of its processing. These features are described in six enums in
|
|
Jackson which map onto properties in the environment:
|
|
|
|
|===
|
|
|Jackson enum|Environment property
|
|
|
|
|`com.fasterxml.jackson.databind.DeserializationFeature`
|
|
|`spring.jackson.deserialization.<feature_name>=true\|false`
|
|
|
|
|`com.fasterxml.jackson.core.JsonGenerator.Feature`
|
|
|`spring.jackson.generator.<feature_name>=true\|false`
|
|
|
|
|`com.fasterxml.jackson.databind.MapperFeature`
|
|
|`spring.jackson.mapper.<feature_name>=true\|false`
|
|
|
|
|`com.fasterxml.jackson.core.JsonParser.Feature`
|
|
|`spring.jackson.parser.<feature_name>=true\|false`
|
|
|
|
|`com.fasterxml.jackson.databind.SerializationFeature`
|
|
|`spring.jackson.serialization.<feature_name>=true\|false`
|
|
|
|
|`com.fasterxml.jackson.annotation.JsonInclude.Include`
|
|
|`spring.jackson.serialization-inclusion=always\|non_null\|non_absent\|non_default\|non_empty`
|
|
|===
|
|
|
|
For example, to enable pretty print, set `spring.jackson.serialization.indent_output=true`.
|
|
Note that, thanks to the use of <<boot-features-external-config-relaxed-binding,
|
|
relaxed binding>>, the case of `indent_output` doesn't have to match the case of the
|
|
corresponding enum constant which is `INDENT_OUTPUT`.
|
|
|
|
This environment-based configuration is applied to the auto-configured
|
|
`Jackson2ObjectMapperBuilder` bean, and will apply to any mappers created
|
|
using the builder, including the auto-configured `ObjectMapper` bean.
|
|
|
|
The context's `Jackson2ObjectMapperBuilder` can be customized by one or more
|
|
`Jackson2ObjectMapperBuilderCustomizer` beans. Such customizer beans can be ordered and
|
|
Boot's own customizer has an order of 0, allowing additional customization to be applied
|
|
both before and after Boot's customization.
|
|
|
|
Any beans of type `com.fasterxml.jackson.databind.Module` will be automatically registered
|
|
with the auto-configured `Jackson2ObjectMapperBuilder` and applied to any `ObjectMapper`
|
|
instances that it creates. This provides a global mechanism for contributing custom
|
|
modules when you add new features to your application.
|
|
|
|
If you want to replace the default `ObjectMapper` completely, either define a `@Bean` of
|
|
that type and mark it as `@Primary`, or, if you prefer the builder-based
|
|
approach, define a `Jackson2ObjectMapperBuilder` `@Bean`. Note that in either case this
|
|
will disable all auto-configuration of the `ObjectMapper.
|
|
|
|
If you provide any `@Beans` of type `MappingJackson2HttpMessageConverter` then
|
|
they will replace the default value in the MVC configuration. Also, a convenience bean is
|
|
provided of type `HttpMessageConverters` (always available if you use the default MVC
|
|
configuration) which has some useful methods to access the default and user-enhanced
|
|
message converters.
|
|
|
|
See also the _<<howto-customize-the-responsebody-rendering>>_ section and the
|
|
{sc-spring-boot-autoconfigure}/web/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`]
|
|
source code for more details.
|
|
|
|
|
|
|
|
[[howto-customize-the-responsebody-rendering]]
|
|
=== Customize the @ResponseBody rendering
|
|
Spring uses `HttpMessageConverters` to render `@ResponseBody` (or responses from
|
|
`@RestController`). You can contribute additional converters by simply adding beans of
|
|
that type in a Spring Boot context. If a bean you add is of a type that would have been
|
|
included by default anyway (like `MappingJackson2HttpMessageConverter` for JSON
|
|
conversions) then it will replace the default value. A convenience bean is provided of
|
|
type `HttpMessageConverters` (always available if you use the default MVC configuration)
|
|
which has some useful methods to access the default and user-enhanced message converters
|
|
(useful, for example if you want to manually inject them into a custom `RestTemplate`).
|
|
|
|
As in normal MVC usage, any `WebMvcConfigurerAdapter` beans that you provide can also
|
|
contribute converters by overriding the `configureMessageConverters` method, but unlike
|
|
with normal MVC, you can supply only additional converters that you need (because Spring
|
|
Boot uses the same mechanism to contribute its defaults). Finally, if you opt-out of the
|
|
Spring Boot default MVC configuration by providing your own `@EnableWebMvc` configuration,
|
|
then you can take control completely and do everything manually using
|
|
`getMessageConverters` from `WebMvcConfigurationSupport`.
|
|
|
|
See the {sc-spring-boot-autoconfigure}/web/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`]
|
|
source code for more details.
|
|
|
|
|
|
|
|
[[howto-multipart-file-upload-configuration]]
|
|
=== Handling Multipart File Uploads
|
|
Spring Boot embraces the Servlet 3 `javax.servlet.http.Part` API to support uploading
|
|
files. By default Spring Boot configures Spring MVC with a maximum file of 1Mb per
|
|
file and a maximum of 10Mb of file data in a single request. You may override these
|
|
values, as well as the location to which intermediate data is stored (e.g., to the `/tmp`
|
|
directory) and the threshold past which data is flushed to disk by using the properties
|
|
exposed in the `MultipartProperties` class. If you want to specify that files be
|
|
unlimited, for example, set the `spring.http.multipart.max-file-size` property to `-1`.
|
|
|
|
The multipart support is helpful when you want to receive multipart encoded file data as
|
|
a `@RequestParam`-annotated parameter of type `MultipartFile` in a Spring MVC controller
|
|
handler method.
|
|
|
|
See the {sc-spring-boot-autoconfigure}/web/MultipartAutoConfiguration.{sc-ext}[`MultipartAutoConfiguration`]
|
|
source for more details.
|
|
|
|
|
|
|
|
[[howto-switch-off-the-spring-mvc-dispatcherservlet]]
|
|
=== Switch off the Spring MVC DispatcherServlet
|
|
Spring Boot wants to serve all content from the root of your application `/` down. If you
|
|
would rather map your own servlet to that URL you can do it, but of course you may lose
|
|
some of the other Boot MVC features. To add your own servlet and map it to the root
|
|
resource just declare a `@Bean` of type `Servlet` and give it the special bean name
|
|
`dispatcherServlet` (You can also create a bean of a different type with that name if
|
|
you want to switch it off and not replace it).
|
|
|
|
|
|
|
|
[[howto-switch-off-default-mvc-configuration]]
|
|
=== Switch off the Default MVC configuration
|
|
The easiest way to take complete control over MVC configuration is to provide your own
|
|
`@Configuration` with the `@EnableWebMvc` annotation. This will leave all MVC
|
|
configuration in your hands.
|
|
|
|
|
|
|
|
[[howto-customize-view-resolvers]]
|
|
=== Customize ViewResolvers
|
|
A `ViewResolver` is a core component of Spring MVC, translating view names in
|
|
`@Controller` to actual `View` implementations. Note that `ViewResolvers` are mainly
|
|
used in UI applications, rather than REST-style services (a `View` is not used to render
|
|
a `@ResponseBody`). There are many implementations of `ViewResolver` to choose from, and
|
|
Spring on its own is not opinionated about which ones you should use. Spring Boot, on the
|
|
other hand, installs one or two for you depending on what it finds on the classpath and
|
|
in the application context. The `DispatcherServlet` uses all the resolvers it finds in
|
|
the application context, trying each one in turn until it gets a result, so if you are
|
|
adding your own you have to be aware of the order and in which position your resolver is
|
|
added.
|
|
|
|
`WebMvcAutoConfiguration` adds the following `ViewResolvers` to your context:
|
|
|
|
* An `InternalResourceViewResolver` with bean id '`defaultViewResolver`'. This one locates
|
|
physical resources that can be rendered using the `DefaultServlet` (e.g. static
|
|
resources and JSP pages if you are using those). It applies a prefix and a suffix to the
|
|
view name and then looks for a physical resource with that path in the servlet context
|
|
(defaults are both empty, but accessible for external configuration via
|
|
`spring.mvc.view.prefix` and `spring.mvc.view.suffix`). It can be overridden by providing a
|
|
bean of the same type.
|
|
* A `BeanNameViewResolver` with id '`beanNameViewResolver`'. This is a useful member of the
|
|
view resolver chain and will pick up any beans with the same name as the `View` being
|
|
resolved. It shouldn't be necessary to override or replace it.
|
|
* A `ContentNegotiatingViewResolver` with id '`viewResolver`' is only added if there *are*
|
|
actually beans of type `View` present. This is a '`master`' resolver, delegating to all
|
|
the others and attempting to find a match to the '`Accept`' HTTP header sent by the
|
|
client. There is a useful
|
|
https://spring.io/blog/2013/06/03/content-negotiation-using-views[blog about `ContentNegotiatingViewResolver`]
|
|
that you might like to study to learn more, and also look at the source code for detail.
|
|
You can switch off the auto-configured
|
|
`ContentNegotiatingViewResolver` by defining a bean named '`viewResolver`'.
|
|
* If you use Thymeleaf you will also have a `ThymeleafViewResolver` with id
|
|
'`thymeleafViewResolver`'. It looks for resources by surrounding the view name with a
|
|
prefix and suffix (externalized to `spring.thymeleaf.prefix` and
|
|
`spring.thymeleaf.suffix`, defaults '`classpath:/templates/`' and '`.html`'
|
|
respectively). It can be overridden by providing a bean of the same name.
|
|
* If you use FreeMarker you will also have a `FreeMarkerViewResolver` with id
|
|
'`freeMarkerViewResolver`'. It looks for resources in a loader path (externalized to
|
|
`spring.freemarker.templateLoaderPath`, default '`classpath:/templates/`') by
|
|
surrounding the view name with a prefix and suffix (externalized to `spring.freemarker.prefix`
|
|
and `spring.freemarker.suffix`, with empty and '`.ftl`' defaults respectively). It can
|
|
be overridden by providing a bean of the same name.
|
|
* If you use Groovy templates (actually if groovy-templates is on your classpath) you will
|
|
also have a `GroovyMarkupViewResolver` with id '`groovyMarkupViewResolver`'. It
|
|
looks for resources in a loader path by surrounding the view name with a prefix and
|
|
suffix (externalized to `spring.groovy.template.prefix` and
|
|
`spring.groovy.template.suffix`, defaults '`classpath:/templates/`' and '`.tpl`'
|
|
respectively). It can be overridden by providing a bean of the same name.
|
|
* If you use Velocity you will also have a `VelocityViewResolver` with id '`velocityViewResolver`'.
|
|
It looks for resources in a loader path (externalized to `spring.velocity.resourceLoaderPath`,
|
|
default '`classpath:/templates/`') by surrounding the view name with a prefix and suffix
|
|
(externalized to `spring.velocity.prefix` and `spring.velocity.suffix`, with empty and '`.vm`'
|
|
defaults respectively). It can be overridden by providing a bean of the same name.
|
|
|
|
Check out {sc-spring-boot-autoconfigure}/web/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`],
|
|
{sc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{sc-ext}[`ThymeleafAutoConfiguration`],
|
|
{sc-spring-boot-autoconfigure}/freemarker/FreeMarkerAutoConfiguration.{sc-ext}[`FreeMarkerAutoConfiguration`],
|
|
{sc-spring-boot-autoconfigure}/groovy/template/GroovyTemplateAutoConfiguration.{sc-ext}[`GroovyTemplateAutoConfiguration`] and
|
|
{sc-spring-boot-autoconfigure}/velocity/VelocityAutoConfiguration.{sc-ext}[`VelocityAutoConfiguration`]
|
|
|
|
|
|
|
|
[[howto-customize-view-resolvers-velocity]]
|
|
=== Velocity
|
|
By default, Spring Boot configures a `VelocityViewResolver`. If you need a
|
|
`VelocityLayoutViewResolver` instead, you can easily configure your own by creating a bean
|
|
with name `velocityViewResolver`. You can also inject the `VelocityProperties` instance to
|
|
apply the base defaults to your custom view resolver.
|
|
|
|
The following example replaces the auto-configured velocity view resolver with a
|
|
`VelocityLayoutViewResolver` defining a customized `layoutUrl` and all settings that would
|
|
have been applied from the auto-configuration:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean(name = "velocityViewResolver")
|
|
public VelocityLayoutViewResolver velocityViewResolver(VelocityProperties properties) {
|
|
VelocityLayoutViewResolver resolver = new VelocityLayoutViewResolver();
|
|
properties.applyToViewResolver(resolver);
|
|
resolver.setLayoutUrl("layout/default.vm");
|
|
return resolver;
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-use-thymeleaf-3]]
|
|
=== Use Thymeleaf 3
|
|
By default, `spring-boot-starter-thymeleaf` uses Thymeleaf 2.1. If you are using the
|
|
`spring-boot-starter-parent`, you can use Thymeleaf 3 by overriding the
|
|
`thymeleaf.version` and `thymeleaf-layout-dialect.version` properties, for example:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<properties>
|
|
<thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
|
|
<thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version>
|
|
</properties>
|
|
----
|
|
|
|
NOTE: if you are managing dependencies yourself, look at `spring-boot-dependencies` for
|
|
the list of artifacts that are related to those two versions.
|
|
|
|
To avoid a warning message about the HTML 5 template mode being deprecated and the HTML
|
|
template mode being used instead, you may also want to explicitly configure
|
|
`spring.thymeleaf.mode` to be `HTML`, for example:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.thymeleaf.mode: HTML
|
|
----
|
|
|
|
Please refer to the
|
|
{github-code}/spring-boot-samples/spring-boot-sample-web-thymeleaf3[Thymeleaf 3 sample] to
|
|
see this in action.
|
|
|
|
If you are using any of the other auto-configured Thymeleaf Extras (Spring Security,
|
|
Data Attribute, or Java 8 Time) you should also override each of their versions to one
|
|
that is compatible with Thymeleaf 3.0.
|
|
|
|
|
|
|
|
[[howto-http-clients]]
|
|
== HTTP clients
|
|
|
|
|
|
|
|
[[howto-http-clients-proxy-configuration]]
|
|
=== Configure RestTemplate to use a proxy
|
|
As described in <<spring-boot-features.adoc#boot-features-restclient-customization>>,
|
|
a `RestTemplateCustomizer` can be used with `RestTemplateBuilder` to build a customized
|
|
`RestTemplate`. This is the recommended approach for creating a `RestTemplate` configured
|
|
to use a proxy.
|
|
|
|
The exact details of the proxy configuration depend on the underlying client request
|
|
factory that is being used. Here's an example of configuring
|
|
`HttpComponentsClientRequestFactory` with an `HttpClient` that uses a proxy for all hosts
|
|
except `192.168.0.5`.
|
|
|
|
[source,java,indent=0]
|
|
----
|
|
include::{code-examples}/web/client/RestTemplateProxyCustomizationExample.java[tag=customizer]
|
|
----
|
|
|
|
|
|
|
|
[[howto-logging]]
|
|
== Logging
|
|
|
|
Spring Boot has no mandatory logging dependency, except for the Commons Logging API, of
|
|
which there are many implementations to choose from. To use https://logback.qos.ch[Logback]
|
|
you need to include it and `jcl-over-slf4j` (which implements the Commons Logging API) on
|
|
the classpath. The simplest way to do that is through the starters which all depend on
|
|
`spring-boot-starter-logging`. For a web application you only need
|
|
`spring-boot-starter-web` since it depends transitively on the logging starter. For
|
|
example, using Maven:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
Spring Boot has a `LoggingSystem` abstraction that attempts to configure logging based on
|
|
the content of the classpath. If Logback is available it is the first choice.
|
|
|
|
If the only change you need to make to logging is to set the levels of various loggers
|
|
then you can do that in `application.properties` using the "logging.level" prefix, e.g.
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
logging.level.org.springframework.web=DEBUG
|
|
logging.level.org.hibernate=ERROR
|
|
----
|
|
|
|
You can also set the location of a file to log to (in addition to the console) using
|
|
"logging.file".
|
|
|
|
To configure the more fine-grained settings of a logging system you need to use the native
|
|
configuration format supported by the `LoggingSystem` in question. By default Spring Boot
|
|
picks up the native configuration from its default location for the system (e.g.
|
|
`classpath:logback.xml` for Logback), but you can set the location of the config file
|
|
using the "logging.config" property.
|
|
|
|
|
|
|
|
[[howto-configure-logback-for-logging]]
|
|
=== Configure Logback for logging
|
|
If you put a `logback.xml` in the root of your classpath it will be picked up from
|
|
there
|
|
(or `logback-spring.xml` to take advantage of the templating features provided by Boot).
|
|
Spring Boot provides a default base configuration that you can include if you just
|
|
want to set levels, e.g.
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<configuration>
|
|
<include resource="org/springframework/boot/logging/logback/base.xml"/>
|
|
<logger name="org.springframework.web" level="DEBUG"/>
|
|
</configuration>
|
|
----
|
|
|
|
If you look at that `base.xml` in the spring-boot jar, you will see that it uses
|
|
some useful System properties which the `LoggingSystem` takes care of creating for you.
|
|
These are:
|
|
|
|
* `${PID}` the current process ID.
|
|
* `${LOG_FILE}` if `logging.file` was set in Boot's external configuration.
|
|
* `${LOG_PATH}` if `logging.path` was set (representing a directory for
|
|
log files to live in).
|
|
* `${LOG_EXCEPTION_CONVERSION_WORD}` if `logging.exception-conversion-word` was set in
|
|
Boot's external configuration.
|
|
|
|
Spring Boot also provides some nice ANSI colour terminal output on a console (but not in
|
|
a log file) using a custom Logback converter. See the default `base.xml` configuration
|
|
for details.
|
|
|
|
If Groovy is on the classpath you should be able to configure Logback with
|
|
`logback.groovy` as well (it will be given preference if present).
|
|
|
|
|
|
|
|
[[howto-configure-logback-for-logging-fileonly]]
|
|
==== Configure logback for file only output
|
|
If you want to disable console logging and write output only to a file you need a custom
|
|
`logback-spring.xml` that imports `file-appender.xml` but not `console-appender.xml`:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<configuration>
|
|
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
|
|
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
|
|
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
|
|
<root level="INFO">
|
|
<appender-ref ref="FILE" />
|
|
</root>
|
|
</configuration>
|
|
----
|
|
|
|
You also need to add `logging.file` to your `application.properties`:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
logging.file=myapplication.log
|
|
----
|
|
|
|
|
|
|
|
[[howto-configure-log4j-for-logging]]
|
|
=== Configure Log4j for logging
|
|
Spring Boot supports https://logging.apache.org/log4j/2.x[Log4j 2] for logging
|
|
configuration if it is on the classpath. If you are using the starters for
|
|
assembling dependencies that means you have to exclude Logback and then include log4j 2
|
|
instead. If you aren't using the starters then you need to provide `jcl-over-slf4j`
|
|
(at least) in addition to Log4j 2.
|
|
|
|
The simplest path is probably through the starters, even though it requires some
|
|
jiggling with excludes, .e.g. in Maven:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter</artifactId>
|
|
<exclusions>
|
|
<exclusion>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-logging</artifactId>
|
|
</exclusion>
|
|
</exclusions>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-log4j2</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
NOTE: The use of the Log4j starters gathers together the dependencies for common logging
|
|
requirements (e.g. including having Tomcat use `java.util.logging` but configuring the
|
|
output using Log4j 2). See the Actuator Log4j 2 samples for more detail and to see it in
|
|
action.
|
|
|
|
|
|
|
|
[[howto-configure-log4j-for-logging-yaml-or-json-config]]
|
|
==== Use YAML or JSON to configure Log4j 2
|
|
In addition to its default XML configuration format, Log4j 2 also supports YAML and JSON
|
|
configuration files. To configure Log4j 2 to use an alternative configuration file format,
|
|
add the appropriate dependencies to the classpath and name your
|
|
configuration files to match your chosen file format:
|
|
|
|
[cols="10,75,15"]
|
|
|===
|
|
|Format|Dependencies|File names
|
|
|
|
|YAML
|
|
a| `com.fasterxml.jackson.core:jackson-databind` +
|
|
`com.fasterxml.jackson.dataformat:jackson-dataformat-yaml`
|
|
a| `log4j2.yaml` +
|
|
`log4j2.yml`
|
|
|
|
|JSON
|
|
a| `com.fasterxml.jackson.core:jackson-databind`
|
|
a| `log4j2.json` +
|
|
`log4j2.jsn`
|
|
|===
|
|
|
|
[[howto-data-access]]
|
|
== Data Access
|
|
|
|
|
|
|
|
[[howto-configure-a-datasource]]
|
|
=== Configure a custom DataSource
|
|
To configure your own `DataSource` define a `@Bean` of that type in your configuration.
|
|
Spring Boot will reuse your `DataSource` anywhere one is required, including database
|
|
initialization. If you need to externalize some settings, you can easily bind your
|
|
`DataSource` to the environment (see
|
|
<<spring-boot-features.adoc#boot-features-external-config-3rd-party-configuration>>).
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean
|
|
@ConfigurationProperties(prefix="app.datasource")
|
|
public DataSource dataSource() {
|
|
return new FancyDataSource();
|
|
}
|
|
----
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.datasource.url=jdbc:h2:mem:mydb
|
|
app.datasource.username=sa
|
|
app.datasource.pool-size=30
|
|
----
|
|
|
|
Assuming that your `FancyDataSource` has regular JavaBean properties for the url, the
|
|
username and the pool size, these settings will be bound automatically before the
|
|
`DataSource` is made available to other components. The regular
|
|
<<howto-initialize-a-database-using-spring-jdbc,database initialization>> will also happen
|
|
(so the relevant sub-set of `spring.datasource.*` can still be used with your custom
|
|
configuration).
|
|
|
|
You can apply the same principle if you are configuring a custom JNDI `DataSource`:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean(destroyMethod="")
|
|
@ConfigurationProperties(prefix="app.datasource")
|
|
public DataSource dataSource() throws Exception {
|
|
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
|
|
return dataSourceLookup.getDataSource("java:comp/env/jdbc/YourDS");
|
|
}
|
|
----
|
|
|
|
Spring Boot also provides a utility builder class `DataSourceBuilder` that can be used to
|
|
create one of the standard data sources (if it is on the classpath). The builder can
|
|
detect the one to use based on what's available on the classpath. It also auto detects the
|
|
driver based on the JDBC url.
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
include::{code-examples}/jdbc/BasicDataSourceExample.java[tag=configuration]
|
|
----
|
|
|
|
To run an app with that `DataSource`, all that is needed really is the connection
|
|
information; pool-specific settings can also be provided, check the implementation that
|
|
is going to be used at runtime for more details.
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.datasource.url=jdbc:mysql://localhost/test
|
|
app.datasource.username=dbuser
|
|
app.datasource.password=dbpass
|
|
app.datasource.pool-size=30
|
|
----
|
|
|
|
There is a catch however. Because the actual type of the connection pool is not exposed,
|
|
no keys are generated in the metadata for your custom `DataSource` and no completion is
|
|
available in your IDE (The `DataSource` interface doesn't expose any property). Also, if
|
|
you happen to _only_ have Hikari on the classpath, this basic setup will not work because
|
|
Hikari has no `url` parameter (but a `jdbcUrl` parameter). You will have to rewrite
|
|
your configuration as follows:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.datasource.jdbc-url=jdbc:mysql://localhost/test
|
|
app.datasource.username=dbuser
|
|
app.datasource.password=dbpass
|
|
app.datasource.maximum-pool-size=30
|
|
----
|
|
|
|
You can fix that by forcing the connection pool to use and return a dedicated
|
|
implementation rather than `DataSource`. You won't be able to change the implementation
|
|
at runtime but the list of options will be explicit.
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
include::{code-examples}/jdbc/SimpleDataSourceExample.java[tag=configuration]
|
|
----
|
|
|
|
You can even go further by leveraging what `DataSourceProperties` does for you, that is
|
|
providing a default embedded database if no url is provided with a sensible username and
|
|
password for it. You can easily initialize a `DataSourceBuilder` from the state of any
|
|
`DataSourceProperties` so you could just as well inject the one Spring Boot creates
|
|
automatically. However, that would split your configuration in two namespaces: url,
|
|
username, password, type and driver on `spring.datasource` and the rest on your custom
|
|
namespace (`app.datasource`). To avoid that, you can redefine a custom
|
|
`DataSourceProperties` on your custom namespace:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
include::{code-examples}/jdbc/ConfigurableDataSourceExample.java[tag=configuration]
|
|
----
|
|
|
|
This setup puts you _in pair_ with what Spring Boot does for you by default, except that
|
|
a dedicated connection pool is chosen (in code) and its settings are exposed in the same
|
|
namespace. Because `DataSourceProperties` is taking care of the `url`/`jdbcUrl`
|
|
translation for you, you can configure it like this:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.datasource.url=jdbc:mysql://localhost/test
|
|
app.datasource.username=dbuser
|
|
app.datasource.password=dbpass
|
|
app.datasource.maximum-pool-size=30
|
|
----
|
|
|
|
NOTE: Because your custom configuration chooses to go with Hikari, `app.datasource.type`
|
|
will have no effect. In practice the builder will be initialized with whatever value you
|
|
might set there and then overridden by the call to `.type()``.
|
|
|
|
See _<<spring-boot-features.adoc#boot-features-configure-datasource>>_ in the
|
|
'`Spring Boot features`' section and the
|
|
{sc-spring-boot-autoconfigure}/jdbc/DataSourceAutoConfiguration.{sc-ext}[`DataSourceAutoConfiguration`]
|
|
class for more details.
|
|
|
|
|
|
|
|
[[howto-two-datasources]]
|
|
=== Configure Two DataSources
|
|
If you need to configure multiple data sources, you can apply the same tricks that are
|
|
described in the previous section. You must, however, mark one of the `DataSource`
|
|
`@Primary` as various auto-configurations down the road expect to be able to get one by
|
|
type.
|
|
|
|
If you create your own `DataSource`, the auto-configuration will back off. In the example
|
|
below, we provide the _exact_ same features set than what the auto-configuration provides
|
|
on the primary data source:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
include::{code-examples}/jdbc/SimpleTwoDataSourcesExample.java[tag=configuration]
|
|
----
|
|
|
|
TIP: `fooDataSourceProperties` has to be flagged `@Primary` so that the database
|
|
initializer feature uses your copy (should you use that).
|
|
|
|
Both data sources are also bound for advanced customizations. For instance you could
|
|
configure them as follows:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.datasource.foo.type=com.zaxxer.hikari.HikariDataSource
|
|
app.datasource.foo.maximum-pool-size=30
|
|
|
|
app.datasource.bar.url=jdbc:mysql://localhost/test
|
|
app.datasource.bar.username=dbuser
|
|
app.datasource.bar.password=dbpass
|
|
app.datasource.bar.max-total=30
|
|
----
|
|
|
|
Of course, you can apply the same concept to the secondary `DataSource` as well:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
include::{code-examples}/jdbc/CompleteTwoDataSourcesExample.java[tag=configuration]
|
|
----
|
|
|
|
This final example configures two data sources on custom namespaces with the same logic
|
|
than what Spring Boot would do in auto-configuration.
|
|
|
|
|
|
|
|
[[howto-use-spring-data-repositories]]
|
|
=== Use Spring Data repositories
|
|
Spring Data can create implementations for you of `@Repository` interfaces of various
|
|
flavors. Spring Boot will handle all of that for you as long as those `@Repositories`
|
|
are included in the same package (or a sub-package) of your `@EnableAutoConfiguration`
|
|
class.
|
|
|
|
For many applications all you will need is to put the right Spring Data dependencies on
|
|
your classpath (there is a `spring-boot-starter-data-jpa` for JPA and a
|
|
`spring-boot-starter-data-mongodb` for Mongodb), create some repository interfaces to handle your
|
|
`@Entity` objects. Examples are in the {github-code}/spring-boot-samples/spring-boot-sample-data-jpa[JPA sample]
|
|
or the {github-code}/spring-boot-samples/spring-boot-sample-data-mongodb[Mongodb sample].
|
|
|
|
Spring Boot tries to guess the location of your `@Repository` definitions, based on the
|
|
`@EnableAutoConfiguration` it finds. To get more control, use the `@EnableJpaRepositories`
|
|
annotation (from Spring Data JPA).
|
|
|
|
|
|
[[howto-separate-entity-definitions-from-spring-configuration]]
|
|
=== Separate @Entity definitions from Spring configuration
|
|
Spring Boot tries to guess the location of your `@Entity` definitions, based on the
|
|
`@EnableAutoConfiguration` it finds. To get more control, you can use the `@EntityScan`
|
|
annotation, e.g.
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Configuration
|
|
@EnableAutoConfiguration
|
|
@EntityScan(basePackageClasses=City.class)
|
|
public class Application {
|
|
|
|
//...
|
|
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-configure-jpa-properties]]
|
|
=== Configure JPA properties
|
|
Spring Data JPA already provides some vendor-independent configuration options (e.g.
|
|
for SQL logging) and Spring Boot exposes those, and a few more for hibernate as external
|
|
configuration properties. The most common options to set are:
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.jpa.hibernate.ddl-auto=create-drop
|
|
spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy
|
|
spring.jpa.database=H2
|
|
spring.jpa.show-sql=true
|
|
----
|
|
|
|
The `ddl-auto` setting is a special case in that it has different defaults depending on
|
|
whether you are using an embedded database (`create-drop`) or not (`none`). In addition
|
|
all properties in `+spring.jpa.properties.*+` are passed through as normal JPA properties
|
|
(with the prefix stripped) when the local `EntityManagerFactory` is created.
|
|
|
|
Spring Boot provides a consistent naming strategy regardless of the Hibernate generation
|
|
that you are using. If you are using Hibernate 4, you can customize it using
|
|
`spring.jpa.hibernate.naming.strategy`; Hibernate 5 defines a `Physical` and `Implicit`
|
|
naming strategies: Spring Boot configures `SpringPhysicalNamingStrategy` by default. This
|
|
implementation provides the same table structure as Hibernate 4. If you'd rather use
|
|
Hibernate 5's default instead, set the following property:
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
|
|
----
|
|
|
|
|
|
See {sc-spring-boot-autoconfigure}/orm/jpa/HibernateJpaAutoConfiguration.{sc-ext}[`HibernateJpaAutoConfiguration`]
|
|
and {sc-spring-boot-autoconfigure}/orm/jpa/JpaBaseConfiguration.{sc-ext}[`JpaBaseConfiguration`]
|
|
for more details.
|
|
|
|
|
|
|
|
[[howto-use-custom-entity-manager]]
|
|
=== Use a custom EntityManagerFactory
|
|
To take full control of the configuration of the `EntityManagerFactory`, you need to add
|
|
a `@Bean` named '`entityManagerFactory`'. Spring Boot auto-configuration switches off its
|
|
entity manager based on the presence of a bean of that type.
|
|
|
|
|
|
|
|
[[howto-use-two-entity-managers]]
|
|
=== Use Two EntityManagers
|
|
Even if the default `EntityManagerFactory` works fine, you will need to define a new one
|
|
because otherwise the presence of the second bean of that type will switch off the
|
|
default. To make it easy to do that you can use the convenient `EntityManagerBuilder`
|
|
provided by Spring Boot, or if you prefer you can just use the
|
|
`LocalContainerEntityManagerFactoryBean` directly from Spring ORM.
|
|
|
|
Example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
// add two data sources configured as above
|
|
|
|
@Bean
|
|
public LocalContainerEntityManagerFactoryBean customerEntityManagerFactory(
|
|
EntityManagerFactoryBuilder builder) {
|
|
return builder
|
|
.dataSource(customerDataSource())
|
|
.packages(Customer.class)
|
|
.persistenceUnit("customers")
|
|
.build();
|
|
}
|
|
|
|
@Bean
|
|
public LocalContainerEntityManagerFactoryBean orderEntityManagerFactory(
|
|
EntityManagerFactoryBuilder builder) {
|
|
return builder
|
|
.dataSource(orderDataSource())
|
|
.packages(Order.class)
|
|
.persistenceUnit("orders")
|
|
.build();
|
|
}
|
|
----
|
|
|
|
The configuration above almost works on its own. To complete the picture you need to
|
|
configure `TransactionManagers` for the two `EntityManagers` as well. One of them could
|
|
be picked up by the default `JpaTransactionManager` in Spring Boot if you mark it as
|
|
`@Primary`. The other would have to be explicitly injected into a new instance. Or you
|
|
might be able to use a JTA transaction manager spanning both.
|
|
|
|
If you are using Spring Data, you need to configure `@EnableJpaRepositories` accordingly:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Configuration
|
|
@EnableJpaRepositories(basePackageClasses = Customer.class,
|
|
entityManagerFactoryRef = "customerEntityManagerFactory")
|
|
public class CustomerConfiguration {
|
|
...
|
|
}
|
|
|
|
@Configuration
|
|
@EnableJpaRepositories(basePackageClasses = Order.class,
|
|
entityManagerFactoryRef = "orderEntityManagerFactory")
|
|
public class OrderConfiguration {
|
|
...
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-use-traditional-persistence-xml]]
|
|
=== Use a traditional persistence.xml
|
|
Spring doesn't require the use of XML to configure the JPA provider, and Spring Boot
|
|
assumes you want to take advantage of that feature. If you prefer to use `persistence.xml`
|
|
then you need to define your own `@Bean` of type `LocalEntityManagerFactoryBean` (with
|
|
id '`entityManagerFactory`', and set the persistence unit name there.
|
|
|
|
See
|
|
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java[`JpaBaseConfiguration`]
|
|
for the default settings.
|
|
|
|
|
|
|
|
[[howto-use-spring-data-jpa--and-mongo-repositories]]
|
|
=== Use Spring Data JPA and Mongo repositories
|
|
|
|
Spring Data JPA and Spring Data Mongo can both create `Repository` implementations for you
|
|
automatically. If they are both present on the classpath, you might have to do some extra
|
|
configuration to tell Spring Boot which one (or both) you want to create repositories for
|
|
you. The most explicit way to do that is to use the standard Spring Data
|
|
`+@Enable*Repositories+` and tell it the location of your `Repository` interfaces
|
|
(where '`*`' is '`Jpa`' or '`Mongo`' or both).
|
|
|
|
There are also flags `+spring.data.*.repositories.enabled+` that you can use to switch the
|
|
auto-configured repositories on and off in external configuration. This is useful for
|
|
instance in case you want to switch off the Mongo repositories and still use the
|
|
auto-configured `MongoTemplate`.
|
|
|
|
The same obstacle and the same features exist for other auto-configured Spring Data
|
|
repository types (Elasticsearch, Solr). Just change the names of the annotations and flags
|
|
respectively.
|
|
|
|
|
|
|
|
[[howto-use-exposing-spring-data-repositories-rest-endpoint]]
|
|
=== Expose Spring Data repositories as REST endpoint
|
|
Spring Data REST can expose the `Repository` implementations as REST endpoints for you as
|
|
long as Spring MVC has been enabled for the application.
|
|
|
|
Spring Boot exposes as set of useful properties from the `spring.data.rest` namespace that
|
|
customize the
|
|
{spring-data-rest-javadoc}/core/config/RepositoryRestConfiguration.{dc-ext}[`RepositoryRestConfiguration`].
|
|
If you need to provide additional customization, you should use a
|
|
{spring-data-rest-javadoc}/webmvc/config/RepositoryRestConfigurer.{dc-ext}[`RepositoryRestConfigurer`]
|
|
bean.
|
|
|
|
|
|
|
|
[[howto-configure-a-component-that-is-used-by-JPA]]
|
|
=== Configure a component that is used by JPA
|
|
If you want to configure a component that will be used by JPA then you need to ensure
|
|
that the component is initialized before JPA. Where the component is auto-configured
|
|
Spring Boot will take care of this for you. For example, when Flyway is auto-configured,
|
|
Hibernate is configured to depend upon Flyway so that the latter has a chance to
|
|
initialize the database before Hibernate tries to use it.
|
|
|
|
If you are configuring a component yourself, you can use an
|
|
`EntityManagerFactoryDependsOnPostProcessor` subclass as a convenient way of setting up
|
|
the necessary dependencies. For example, if you are using Hibernate Search with
|
|
Elasticsearch as its index manager then any `EntityManagerFactory` beans must be
|
|
configured to depend on the `elasticsearchClient` bean:
|
|
|
|
[source,java,indent=0]
|
|
----
|
|
include::{code-examples}/elasticsearch/HibernateSearchElasticsearchExample.java[tag=configuration]
|
|
----
|
|
|
|
|
|
|
|
[[howto-database-initialization]]
|
|
== Database initialization
|
|
An SQL database can be initialized in different ways depending on what your stack is. Or
|
|
of course you can do it manually as long as the database is a separate process.
|
|
|
|
|
|
|
|
[[howto-initialize-a-database-using-jpa]]
|
|
=== Initialize a database using JPA
|
|
JPA has features for DDL generation, and these can be set up to run on startup against the
|
|
database. This is controlled through two external properties:
|
|
|
|
* `spring.jpa.generate-ddl` (boolean) switches the feature on and off and is vendor
|
|
independent.
|
|
* `spring.jpa.hibernate.ddl-auto` (enum) is a Hibernate feature that controls the
|
|
behavior in a more fine-grained way. See below for more detail.
|
|
|
|
|
|
|
|
[[howto-initialize-a-database-using-hibernate]]
|
|
=== Initialize a database using Hibernate
|
|
You can set `spring.jpa.hibernate.ddl-auto` explicitly and the standard Hibernate property
|
|
values are `none`, `validate`, `update`, `create`, `create-drop`. Spring Boot chooses a
|
|
default value for you based on whether it thinks your database is embedded (default
|
|
`create-drop`) or not (default `none`). An embedded database is detected by looking at the
|
|
`Connection` type: `hsqldb`, `h2` and `derby` are embedded, the rest are not. Be careful
|
|
when switching from in-memory to a '`real`' database that you don't make assumptions about
|
|
the existence of the tables and data in the new platform. You either have to set `ddl-auto`
|
|
explicitly, or use one of the other mechanisms to initialize the database.
|
|
|
|
NOTE: You can output the schema creation by enabling the `org.hibernate.SQL` logger. This
|
|
is done for you automatically if you enable the <<boot-features-logging-console-output,debug mode>>.
|
|
|
|
In addition, a file named `import.sql` in the root of the classpath will be executed on
|
|
startup if Hibernate creates the schema from scratch (that is if the `ddl-auto` property
|
|
is set to `create` or `create-drop`). This can be useful for demos and for testing if you
|
|
are careful, but probably not something you want to be on the classpath in production. It
|
|
is a Hibernate feature (nothing to do with Spring).
|
|
|
|
|
|
[[howto-initialize-a-database-using-spring-jdbc]]
|
|
=== Initialize a database using Spring JDBC
|
|
Spring JDBC has a `DataSource` initializer feature. Spring Boot enables it by default and
|
|
loads SQL from the standard locations `schema.sql` and `data.sql` (in the root of the
|
|
classpath). In addition Spring Boot will load the `schema-${platform}.sql`
|
|
and `data-${platform}.sql` files (if present), where
|
|
`platform` is the value of `spring.datasource.platform`, e.g. you might choose to set
|
|
it to the vendor name of the database (`hsqldb`, `h2`, `oracle`, `mysql`,
|
|
`postgresql` etc.). Spring Boot enables the fail-fast feature of the Spring JDBC
|
|
initializer by default, so if the scripts cause exceptions the application will fail
|
|
to start. The script locations can be changed by setting `spring.datasource.schema` and
|
|
`spring.datasource.data`, and neither location will be processed if
|
|
`spring.datasource.initialize=false`.
|
|
|
|
To disable the fail-fast you can set `spring.datasource.continue-on-error=true`. This can be
|
|
useful once an application has matured and been deployed a few times, since the scripts
|
|
can act as '`poor man's migrations`' -- inserts that fail mean that the data is already
|
|
there, so there would be no need to prevent the application from running, for instance.
|
|
|
|
If you want to use the `schema.sql` initialization in a JPA app (with
|
|
Hibernate) then `ddl-auto=create-drop` will lead to errors if
|
|
Hibernate tries to create the same tables. To avoid those errors set
|
|
`ddl-auto` explicitly to "" (preferable) or "none". Whether or not you use
|
|
`ddl-auto=create-drop` you can always use `data.sql` to initialize new
|
|
data.
|
|
|
|
|
|
|
|
[[howto-initialize-a-spring-batch-database]]
|
|
=== Initialize a Spring Batch database
|
|
If you are using Spring Batch then it comes pre-packaged with SQL initialization scripts
|
|
for most popular database platforms. Spring Boot will detect your database type, and
|
|
execute those scripts by default, and in this case will switch the fail fast setting to
|
|
false (errors are logged but do not prevent the application from starting). This is
|
|
because the scripts are known to be reliable and generally do not contain bugs, so errors
|
|
are ignorable, and ignoring them makes the scripts idempotent. You can switch off the
|
|
initialization explicitly using `spring.batch.initializer.enabled=false`.
|
|
|
|
|
|
|
|
[[howto-use-a-higher-level-database-migration-tool]]
|
|
=== Use a higher-level database migration tool
|
|
Spring Boot supports two higher-level migration tools: https://flywaydb.org/[Flyway]
|
|
and https://www.liquibase.org/[Liquibase].
|
|
|
|
|
|
|
|
[[howto-execute-flyway-database-migrations-on-startup]]
|
|
==== Execute Flyway database migrations on startup
|
|
To automatically run Flyway database migrations on startup, add the
|
|
`org.flywaydb:flyway-core` to your classpath.
|
|
|
|
The migrations are scripts in the form `V<VERSION>__<NAME>.sql` (with `<VERSION>` an
|
|
underscore-separated version, e.g. '`1`' or '`2_1`'). By default they live in a folder
|
|
`classpath:db/migration` but you can modify that using `flyway.locations` (a list). See
|
|
the Flyway class from flyway-core for details of available settings like schemas etc. In
|
|
addition Spring Boot provides a small set of properties in
|
|
{sc-spring-boot-autoconfigure}/flyway/FlywayProperties.{sc-ext}[`FlywayProperties`]
|
|
that can be used to disable the migrations, or switch off the location checking. Spring
|
|
Boot will call `Flyway.migrate()` to perform the database migration. If you would like
|
|
more control, provide a `@Bean` that implements
|
|
{sc-spring-boot-autoconfigure}/flyway/FlywayMigrationStrategy.{sc-ext}[`FlywayMigrationStrategy`].
|
|
|
|
TIP: If you want to make use of https://flywaydb.org/documentation/callbacks.html[Flyway
|
|
callbacks], those scripts should also live in the `classpath:db/migration` folder.
|
|
|
|
By default Flyway will autowire the (`@Primary`) `DataSource` in your context and
|
|
use that for migrations. If you like to use a different `DataSource` you can create
|
|
one and mark its `@Bean` as `@FlywayDataSource` - if you do that remember to create
|
|
another one and mark it as `@Primary` if you want two data sources.
|
|
Or you can use Flyway's native `DataSource` by setting `flyway.[url,user,password]`
|
|
in external properties.
|
|
|
|
There is a {github-code}/spring-boot-samples/spring-boot-sample-flyway[Flyway sample] so
|
|
you can see how to set things up.
|
|
|
|
You can also use Flyway to provide data for specific scenarios. For example, you can
|
|
place test-specific migrations in `src/test/resources` and they will only be run when your
|
|
application starts for testing. If you want to be more sophisticated you can use
|
|
profile-specific configuration to customize `flyway.locations` so that certain migrations
|
|
will only run when a particular profile is active. For example, in
|
|
`application-dev.properties` you could set `flyway.locations` to
|
|
`classpath:/db/migration, claspath:/dev/db/migration` and migrations in `dev/db/migration`
|
|
will only run when the `dev` profile is active.
|
|
|
|
|
|
|
|
[[howto-execute-liquibase-database-migrations-on-startup]]
|
|
==== Execute Liquibase database migrations on startup
|
|
To automatically run Liquibase database migrations on startup, add the
|
|
`org.liquibase:liquibase-core` to your classpath.
|
|
|
|
The master change log is by default read from `db/changelog/db.changelog-master.yaml` but
|
|
can be set using `liquibase.change-log`. In addition to YAML, Liquibase also supports
|
|
JSON, XML, and SQL change log formats.
|
|
|
|
By default Liquibase will autowire the (`@Primary`) `DataSource` in your context and use
|
|
that for migrations. If you like to use a different `DataSource` you can create one and
|
|
mark its `@Bean` as `@LiquibaseDataSource` - if you do that remember to create another one
|
|
and mark it as `@Primary` if you want two data sources. Or you can use Liquibase's native
|
|
`DataSource` by setting `liquibase.[url,user,password]` in external properties.
|
|
|
|
See
|
|
{sc-spring-boot-autoconfigure}/liquibase/LiquibaseProperties.{sc-ext}[`LiquibaseProperties`]
|
|
for details of available settings like contexts, default schema etc.
|
|
|
|
There is a {github-code}/spring-boot-samples/spring-boot-sample-liquibase[Liquibase sample]
|
|
so you can see how to set things up.
|
|
|
|
|
|
|
|
[[howto-messaging]]
|
|
== Messaging
|
|
|
|
|
|
|
|
[[howto-jms-disable-transaction]]
|
|
=== Disable transacted JMS session
|
|
If your JMS broker does not support transacted session, you will have to disable the
|
|
support of transactions altogether. If you create your own `JmsListenerContainerFactory`
|
|
there is nothing to do since it won't be transacted by default. If you want to use
|
|
the `DefaultJmsListenerContainerFactoryConfigurer` to reuse Spring Boot's default, you
|
|
can disable transacted session as follows:
|
|
|
|
[source,java,indent=0]
|
|
----
|
|
@Bean
|
|
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(
|
|
ConnectionFactory connectionFactory,
|
|
DefaultJmsListenerContainerFactoryConfigurer configurer) {
|
|
DefaultJmsListenerContainerFactory listenerFactory =
|
|
new DefaultJmsListenerContainerFactory();
|
|
configurer.configure(listenerFactory, connectionFactory);
|
|
listenerFactory.setTransactionManager(null);
|
|
listenerFactory.setSessionTransacted(false);
|
|
return listenerFactory;
|
|
}
|
|
----
|
|
|
|
This overrides the default factory and this should be applied to any other factory that
|
|
your application defines, if any.
|
|
|
|
|
|
|
|
[[howto-batch-applications]]
|
|
== Batch applications
|
|
|
|
NOTE: By default, batch applications require a `DataSource` to store job details. If you
|
|
want to deviate from that, you'll need to implement `BatchConfigurer`, see
|
|
{spring-batch-javadoc}/core/configuration/annotation/EnableBatchProcessing.html[The
|
|
Javadoc of `@EnableBatchProcessing`] for more details.
|
|
|
|
|
|
|
|
[[howto-execute-spring-batch-jobs-on-startup]]
|
|
=== Execute Spring Batch jobs on startup
|
|
Spring Batch auto-configuration is enabled by adding `@EnableBatchProcessing`
|
|
(from Spring Batch) somewhere in your context.
|
|
|
|
By default it executes *all* `Jobs` in the application context on startup (see
|
|
{sc-spring-boot-autoconfigure}/batch/JobLauncherCommandLineRunner.{sc-ext}[JobLauncherCommandLineRunner]
|
|
for details). You can narrow down to a specific job or jobs by specifying
|
|
`spring.batch.job.names` (comma-separated job name patterns).
|
|
|
|
If the application context includes a `JobRegistry` then the jobs in
|
|
`spring.batch.job.names` are looked up in the registry instead of being autowired from the
|
|
context. This is a common pattern with more complex systems where multiple jobs are
|
|
defined in child contexts and registered centrally.
|
|
|
|
See
|
|
{sc-spring-boot-autoconfigure}/batch/BatchAutoConfiguration.{sc-ext}[BatchAutoConfiguration]
|
|
and
|
|
https://github.com/spring-projects/spring-batch/blob/master/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java[@EnableBatchProcessing]
|
|
for more details.
|
|
|
|
|
|
|
|
[[howto-actuator]]
|
|
== Actuator
|
|
|
|
|
|
|
|
[[howto-change-the-http-port-or-address-of-the-actuator-endpoints]]
|
|
=== Change the HTTP port or address of the actuator endpoints
|
|
In a standalone application the Actuator HTTP port defaults to the same as the main HTTP
|
|
port. To make the application listen on a different port set the external property
|
|
`management.port`. To listen on a completely different network address (e.g. if you have
|
|
an internal network for management and an external one for user applications) you can
|
|
also set `management.address` to a valid IP address that the server is able to bind to.
|
|
|
|
For more detail look at the
|
|
{sc-spring-boot-actuator}/autoconfigure/ManagementServerProperties.{sc-ext}[`ManagementServerProperties`]
|
|
source code and
|
|
_<<production-ready-features.adoc#production-ready-customizing-management-server-port>>_
|
|
in the '`Production-ready features`' section.
|
|
|
|
|
|
|
|
[[howto-customize-the-whitelabel-error-page]]
|
|
=== Customize the '`whitelabel`' error page
|
|
Spring Boot installs a '`whitelabel`' error page that you will see in browser client if
|
|
you encounter a server error (machine clients consuming JSON and other media types should
|
|
see a sensible response with the right error code).
|
|
|
|
NOTE: Set `server.error.whitelabel.enabled=false` to switch the default error page off
|
|
which will restore the default of the servlet container that you are using. Note that
|
|
Spring Boot will still attempt to resolve the error view so you'd probably add you own
|
|
error page rather than disabling it completely.
|
|
|
|
Overriding the error page with your own depends on the templating technology that you are
|
|
using. For example, if you are using Thymeleaf you would add an `error.html` template and
|
|
if you are using FreeMarker you would add an `error.ftl` template. In general what you
|
|
need is a `View` that resolves with a name of `error`, and/or a `@Controller` that handles
|
|
the `/error` path. Unless you replaced some of the default configuration you should find
|
|
a `BeanNameViewResolver` in your `ApplicationContext` so a `@Bean` with id `error` would
|
|
be a simple way of doing that. Look at
|
|
{sc-spring-boot-autoconfigure}/web/ErrorMvcAutoConfiguration.{sc-ext}[`ErrorMvcAutoConfiguration`] for more options.
|
|
|
|
See also the section on <<boot-features-error-handling, Error Handling>> for details of
|
|
how to register handlers in the servlet container.
|
|
|
|
|
|
|
|
[[howto-use-actuator-with-jersey]]
|
|
=== Actuator and Jersey
|
|
Actuator HTTP endpoints are only available for Spring MVC-based applications. If you want
|
|
to use Jersey and still use the actuator you will need to enable Spring MVC (by depending
|
|
on `spring-boot-starter-web`, for example). By default, both Jersey and the Spring MVC
|
|
dispatcher servlet are mapped to the same path (`/`). You will need to change the path for
|
|
one of them (by configuring `server.servlet-path` for Spring MVC or
|
|
`spring.jersey.application-path` for Jersey). For example, if you add
|
|
`server.servlet-path=/system` into `application.properties`, the actuator HTTP endpoints
|
|
will be available under `/system`.
|
|
|
|
|
|
|
|
[[howto-security]]
|
|
== Security
|
|
|
|
|
|
[[howto-switch-off-spring-boot-security-configuration]]
|
|
=== Switch off the Spring Boot security configuration
|
|
If you define a `@Configuration` with `@EnableWebSecurity` anywhere in your application
|
|
it will switch off the default webapp security settings in Spring Boot (but leave the
|
|
Actuator's security enabled). To tweak the defaults try setting properties in
|
|
`+security.*+` (see
|
|
{sc-spring-boot-autoconfigure}/security/SecurityProperties.{sc-ext}[`SecurityProperties`]
|
|
for details of available settings) and `SECURITY` section of
|
|
<<common-application-properties-security,Common application properties>>.
|
|
|
|
|
|
|
|
[[howto-change-the-authenticationmanager-and-add-user-accounts]]
|
|
=== Change the AuthenticationManager and add user accounts
|
|
If you provide a `@Bean` of type `AuthenticationManager` the default one will not be
|
|
created, so you have the full feature set of Spring Security available (e.g.
|
|
https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#jc-authentication[various authentication options]).
|
|
|
|
Spring Security also provides a convenient `AuthenticationManagerBuilder` which can be
|
|
used to build an `AuthenticationManager` with common options. The recommended way to
|
|
use this in a webapp is to inject it into a void method in a
|
|
`WebSecurityConfigurerAdapter`, e.g.
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Configuration
|
|
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
|
|
|
@Autowired
|
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
|
auth.inMemoryAuthentication()
|
|
.withUser("barry").password("password").roles("USER"); // ... etc.
|
|
}
|
|
|
|
// ... other stuff for application security
|
|
|
|
}
|
|
----
|
|
|
|
You will get the best results if you put this in a nested class, or a standalone class
|
|
(i.e. not mixed in with a lot of other `@Beans` that might be allowed to influence the
|
|
order of instantiation). The {github-code}/spring-boot-samples/spring-boot-sample-web-secure[secure web sample]
|
|
is a useful template to follow.
|
|
|
|
If you experience instantiation issues (e.g. using JDBC or JPA for the user detail store)
|
|
it might be worth extracting the `AuthenticationManagerBuilder` callback into a
|
|
`GlobalAuthenticationConfigurerAdapter` (in the `init()` method so it happens before the
|
|
authentication manager is needed elsewhere), e.g.
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Configuration
|
|
public class AuthenticationManagerConfiguration extends
|
|
GlobalAuthenticationConfigurerAdapter {
|
|
|
|
@Override
|
|
public void init(AuthenticationManagerBuilder auth) {
|
|
auth.inMemoryAuthentication() // ... etc.
|
|
}
|
|
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-enable-https]]
|
|
=== Enable HTTPS when running behind a proxy server
|
|
Ensuring that all your main endpoints are only available over HTTPS is an important
|
|
chore for any application. If you are using Tomcat as a servlet container, then
|
|
Spring Boot will add Tomcat's own `RemoteIpValve` automatically if it detects some
|
|
environment settings, and you should be able to rely on the `HttpServletRequest` to
|
|
report whether it is secure or not (even downstream of a proxy server that handles the
|
|
real SSL termination). The standard behavior is determined by the presence or absence of
|
|
certain request headers (`x-forwarded-for` and `x-forwarded-proto`), whose names are
|
|
conventional, so it should work with most front end proxies. You can switch on the valve
|
|
by adding some entries to `application.properties`, e.g.
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
server.tomcat.remote_ip_header=x-forwarded-for
|
|
server.tomcat.protocol_header=x-forwarded-proto
|
|
----
|
|
|
|
(The presence of either of those properties will switch on the valve. Or you can add the
|
|
`RemoteIpValve` yourself by adding a `TomcatEmbeddedServletContainerFactory` bean.)
|
|
|
|
Spring Security can also be configured to require a secure channel for all (or some
|
|
requests). To switch that on in a Spring Boot application you just need to set
|
|
`security.require_ssl` to `true` in `application.properties`.
|
|
|
|
|
|
|
|
[[howto-hotswapping]]
|
|
== Hot swapping
|
|
|
|
|
|
|
|
[[howto-reload-static-content]]
|
|
=== Reload static content
|
|
There are several options for hot reloading. The recommended approach is to use
|
|
<<using-spring-boot.adoc#using-boot-devtools,`spring-boot-devtools`>> as it provides
|
|
additional development-time features such as support for fast application restarts
|
|
and LiveReload as well as sensible development-time configuration (e.g. template caching).
|
|
Devtools works by monitoring the classpath for changes. This means that static resource
|
|
changes must be "built" for the change to take affect. By default, this happens
|
|
automatically in Eclipse when you save your changes. In IntelliJ IDEA, Make Project will
|
|
trigger the necessary build. Due to the
|
|
<<using-spring-boot.adoc#using-boot-devtools-restart-exclude, default restart
|
|
exclusions>>, changes to static resources will not trigger a restart of your application.
|
|
They will, however, trigger a live reload.
|
|
|
|
Alternatively, running in an IDE (especially with debugging on) is a good way to do
|
|
development (all modern IDEs allow reloading of static resources and usually also
|
|
hot-swapping of Java class changes).
|
|
|
|
Finally, the <<build-tool-plugins.adoc#build-tool-plugins, Maven and Gradle plugins>> can
|
|
be configured (see the `addResources` property) to support running from the command line
|
|
with reloading of static files directly from source. You can use that with an external
|
|
css/js compiler process if you are writing that code with higher level tools.
|
|
|
|
|
|
|
|
[[howto-reload-thymeleaf-template-content]]
|
|
=== Reload templates without restarting the container
|
|
Most of the templating technologies supported by Spring Boot include a configuration
|
|
option to disable caching (see below for details). If you're using the
|
|
`spring-boot-devtools` module these properties will be
|
|
<<using-spring-boot.adoc#using-boot-devtools-property-defaults,automatically configured>>
|
|
for you at development time.
|
|
|
|
|
|
|
|
[[howto-reload-thymeleaf-content]]
|
|
==== Thymeleaf templates
|
|
If you are using Thymeleaf, then set `spring.thymeleaf.cache` to `false`. See
|
|
{sc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{sc-ext}[`ThymeleafAutoConfiguration`]
|
|
for other Thymeleaf customization options.
|
|
|
|
|
|
|
|
[[howto-reload-freemarker-content]]
|
|
==== FreeMarker templates
|
|
If you are using FreeMarker, then set `spring.freemarker.cache` to `false`. See
|
|
{sc-spring-boot-autoconfigure}/freemarker/FreeMarkerAutoConfiguration.{sc-ext}[`FreeMarkerAutoConfiguration`]
|
|
for other FreeMarker customization options.
|
|
|
|
|
|
|
|
[[howto-reload-groovy-template-content]]
|
|
==== Groovy templates
|
|
If you are using Groovy templates, then set `spring.groovy.template.cache` to `false`. See
|
|
{sc-spring-boot-autoconfigure}/groovy/template/GroovyTemplateAutoConfiguration.{sc-ext}[`GroovyTemplateAutoConfiguration`]
|
|
for other Groovy customization options.
|
|
|
|
|
|
|
|
[[howto-reload-velocity-content]]
|
|
==== Velocity templates
|
|
If you are using Velocity, then set `spring.velocity.cache` to `false`. See
|
|
{sc-spring-boot-autoconfigure}/velocity/VelocityAutoConfiguration.{sc-ext}[`VelocityAutoConfiguration`]
|
|
for other Velocity customization options.
|
|
|
|
|
|
|
|
[[howto-reload-fast-restart]]
|
|
=== Fast application restarts
|
|
The `spring-boot-devtools` module includes support for automatic application restarts.
|
|
Whilst not as fast a technologies such as https://zeroturnaround.com/software/jrebel/[JRebel]
|
|
or https://github.com/spring-projects/spring-loaded[Spring Loaded] it's usually
|
|
significantly faster than a "`cold start`". You should probably give it a try before
|
|
investigating some of the more complex reload options discussed below.
|
|
|
|
For more details see the <<using-spring-boot.adoc#using-boot-devtools>> section.
|
|
|
|
|
|
[[howto-reload-java-classes-without-restarting]]
|
|
=== Reload Java classes without restarting the container
|
|
Modern IDEs (Eclipse, IDEA, etc.) all support hot swapping of bytecode, so if you make a
|
|
change that doesn't affect class or method signatures it should reload cleanly with no
|
|
side effects.
|
|
|
|
https://github.com/spring-projects/spring-loaded[Spring Loaded] goes a little further in
|
|
that it can reload class definitions with changes in the method signatures. With some
|
|
customization it can force an `ApplicationContext` to refresh itself (but there is no
|
|
general mechanism to ensure that would be safe for a running application anyway, so it
|
|
would only ever be a development time trick probably).
|
|
|
|
|
|
[[howto-reload-springloaded-maven]]
|
|
==== Configuring Spring Loaded for use with Maven
|
|
To use Spring Loaded with the Maven command line, just add it as a dependency in the
|
|
Spring Boot plugin declaration, e.g.
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
<dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework</groupId>
|
|
<artifactId>springloaded</artifactId>
|
|
<version>1.2.6.RELEASE</version>
|
|
</dependency>
|
|
</dependencies>
|
|
</plugin>
|
|
----
|
|
|
|
This normally works pretty well with Eclipse and IntelliJ IDEA as long as they have their
|
|
build configuration aligned with the Maven defaults (Eclipse m2e does this out of the
|
|
box).
|
|
|
|
|
|
|
|
[[howto-reload-springloaded-gradle-and-intellij-idea]]
|
|
==== Configuring Spring Loaded for use with Gradle and IntelliJ IDEA
|
|
You need to jump through a few hoops if you want to use Spring Loaded in combination with
|
|
Gradle and IntelliJ IDEA. By default, IntelliJ IDEA will compile classes into a different
|
|
location than Gradle, causing Spring Loaded monitoring to fail.
|
|
|
|
To configure IntelliJ IDEA correctly you can use the `idea` Gradle plugin:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
buildscript {
|
|
repositories { jcenter() }
|
|
dependencies {
|
|
classpath "org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}"
|
|
classpath 'org.springframework:springloaded:1.2.6.RELEASE'
|
|
}
|
|
}
|
|
|
|
apply plugin: 'idea'
|
|
|
|
idea {
|
|
module {
|
|
inheritOutputDirs = false
|
|
outputDir = file("$buildDir/classes/main/")
|
|
}
|
|
}
|
|
|
|
// ...
|
|
|
|
----
|
|
|
|
NOTE: IntelliJ IDEA must be configured to use the same Java version as the command line
|
|
Gradle task and `springloaded` *must* be included as a `buildscript` dependency.
|
|
|
|
You can also additionally enable '`Make Project Automatically`' inside IntelliJ IDEA to
|
|
automatically compile your code whenever a file is saved.
|
|
|
|
|
|
|
|
[[howto-build]]
|
|
== Build
|
|
|
|
|
|
|
|
[[howto-build-info]]
|
|
=== Generate build information
|
|
Both the Maven and Gradle plugin allow to generate build information containing
|
|
the coordinates, name and version of the project. The plugin can also be configured
|
|
to add additional properties through configuration. When such file is present,
|
|
Spring Boot auto-configures a `BuildProperties` bean.
|
|
|
|
To generate build information with Maven, add an execution for the `build-info` goal:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
<version>{spring-boot-version}</version>
|
|
<executions>
|
|
<execution>
|
|
<goals>
|
|
<goal>build-info</goal>
|
|
</goals>
|
|
</execution>
|
|
</executions>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
TIP: Check the {spring-boot-maven-plugin-site}/[Spring Boot Maven Plugin documentation]
|
|
for more details.
|
|
|
|
And to do the same with Gradle:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
springBoot {
|
|
buildInfo()
|
|
}
|
|
----
|
|
|
|
Additional properties can be added using the DSL:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
springBoot {
|
|
buildInfo {
|
|
additionalProperties = [
|
|
'foo': 'bar'
|
|
]
|
|
}
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-git-info]]
|
|
=== Generate git information
|
|
|
|
Both Maven and Gradle allow to generate a `git.properties` file containing information
|
|
about the state of your `git` source code repository when the project was built.
|
|
|
|
For Maven users the `spring-boot-starter-parent` POM includes a pre-configured plugin to
|
|
generate a `git.properties` file. Simply add the following declaration to your POM:
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>pl.project13.maven</groupId>
|
|
<artifactId>git-commit-id-plugin</artifactId>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
Gradle users can achieve the same result using the
|
|
https://plugins.gradle.org/plugin/com.gorylenko.gradle-git-properties[`gradle-git-properties`] plugin
|
|
|
|
[source,groovy,indent=0]
|
|
----
|
|
plugins {
|
|
id "com.gorylenko.gradle-git-properties" version "1.4.6"
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-customize-dependency-versions-with-maven]]
|
|
[[howto-customize-dependency-versions]]
|
|
=== Customize dependency versions
|
|
If you use a Maven build that inherits directly or indirectly from `spring-boot-dependencies`
|
|
(for instance `spring-boot-starter-parent`) but you want to override a specific
|
|
third-party dependency you can add appropriate `<properties>` elements. Browse
|
|
the {github-code}/spring-boot-dependencies/pom.xml[`spring-boot-dependencies`]
|
|
POM for a complete list of properties. For example, to pick a different `slf4j` version
|
|
you would add the following:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<properties>
|
|
<slf4j.version>1.7.5<slf4j.version>
|
|
</properties>
|
|
----
|
|
|
|
NOTE: This only works if your Maven project inherits (directly or indirectly) from
|
|
`spring-boot-dependencies`. If you have added `spring-boot-dependencies` in your
|
|
own `dependencyManagement` section with `<scope>import</scope>` you have to redefine
|
|
the artifact yourself instead of overriding the property.
|
|
|
|
WARNING: Each Spring Boot release is designed and tested against a specific set of
|
|
third-party dependencies. Overriding versions may cause compatibility issues.
|
|
|
|
To override dependency versions in Gradle, you can specify a version as shown below:
|
|
|
|
[source,groovy,indent=0]
|
|
----
|
|
ext['slf4j.version'] = '1.7.5'
|
|
----
|
|
|
|
For additional information, please refer to the
|
|
https://github.com/spring-gradle-plugins/dependency-management-plugin[Gradle Dependency
|
|
Management Plugin documentation].
|
|
|
|
[[howto-create-an-executable-jar-with-maven]]
|
|
=== Create an executable JAR with Maven
|
|
The `spring-boot-maven-plugin` can be used to create an executable '`fat`' JAR. If you
|
|
are using the `spring-boot-starter-parent` POM you can simply declare the plugin and
|
|
your jars will be repackaged:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
If you are not using the parent POM you can still use the plugin, however, you must
|
|
additionally add an `<executions>` section:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
<version>{spring-boot-version}</version>
|
|
<executions>
|
|
<execution>
|
|
<goals>
|
|
<goal>repackage</goal>
|
|
</goals>
|
|
</execution>
|
|
</executions>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
See the {spring-boot-maven-plugin-site}/usage.html[plugin documentation] for full usage
|
|
details.
|
|
|
|
|
|
[[howto-create-an-additional-executable-jar]]
|
|
=== Use a Spring Boot application as a dependency
|
|
Like a war file, a Spring Boot application is not intended to be used as a dependency. If
|
|
your application contains classes that you want to share with other projects, the
|
|
recommended approach is to move that code into a separate module. The separate module can
|
|
then be depended upon by your application and other projects.
|
|
|
|
If you cannot rearrange your code as recommended above, Spring Boot's Maven and Gradle
|
|
plugins must be configured to produce a separate artifact that is suitable for use as a
|
|
dependency. The executable archive cannot be used as a dependency as the
|
|
<<appendix-executable-jar-format.adoc#executable-jar-jar-file-structure,executable jar
|
|
format>> packages application classes in `BOOT-INF/classes`. This means
|
|
that they cannot be found when the executable jar is used as a dependency.
|
|
|
|
To produce the two artifacts, one that can be used as a dependency and one that is
|
|
executable, a classifier must be specified. This classifier is applied to the name of the
|
|
executable archive, leaving the default archive for use as dependency.
|
|
|
|
To configure a classifier of `exec` in Maven, the following configuration can be used:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
<configuration>
|
|
<classifier>exec</classifier>
|
|
</configuration>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
And when using Gradle, the following configuration can be used:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
bootRepackage {
|
|
classifier = 'exec'
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-extract-specific-libraries-when-an-executable-jar-runs]]
|
|
=== Extract specific libraries when an executable jar runs
|
|
Most nested libraries in an executable jar do not need to be unpacked in order to run,
|
|
however, certain libraries can have problems. For example, JRuby includes its own nested
|
|
jar support which assumes that the `jruby-complete.jar` is always directly available as a
|
|
file in its own right.
|
|
|
|
To deal with any problematic libraries, you can flag that specific nested jars should be
|
|
automatically unpacked to the '`temp folder`' when the executable jar first runs.
|
|
|
|
For example, to indicate that JRuby should be flagged for unpack using the Maven Plugin
|
|
you would add the following configuration:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
<configuration>
|
|
<requiresUnpack>
|
|
<dependency>
|
|
<groupId>org.jruby</groupId>
|
|
<artifactId>jruby-complete</artifactId>
|
|
</dependency>
|
|
</requiresUnpack>
|
|
</configuration>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
And to do that same with Gradle:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
springBoot {
|
|
requiresUnpack = ['org.jruby:jruby-complete']
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-create-a-nonexecutable-jar]]
|
|
=== Create a non-executable JAR with exclusions
|
|
Often if you have an executable and a non-executable jar as build products, the executable
|
|
version will have additional configuration files that are not needed in a library jar.
|
|
E.g. the `application.yml` configuration file might excluded from the non-executable JAR.
|
|
|
|
Here's how to do that in Maven:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
<configuration>
|
|
<classifier>exec</classifier>
|
|
</configuration>
|
|
</plugin>
|
|
<plugin>
|
|
<artifactId>maven-jar-plugin</artifactId>
|
|
<executions>
|
|
<execution>
|
|
<id>exec</id>
|
|
<phase>package</phase>
|
|
<goals>
|
|
<goal>jar</goal>
|
|
</goals>
|
|
<configuration>
|
|
<classifier>exec</classifier>
|
|
</configuration>
|
|
</execution>
|
|
<execution>
|
|
<phase>package</phase>
|
|
<goals>
|
|
<goal>jar</goal>
|
|
</goals>
|
|
<configuration>
|
|
<!-- Need this to ensure application.yml is excluded -->
|
|
<forceCreation>true</forceCreation>
|
|
<excludes>
|
|
<exclude>application.yml</exclude>
|
|
</excludes>
|
|
</configuration>
|
|
</execution>
|
|
</executions>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
In Gradle you can create a new JAR archive with standard task DSL features, and then have
|
|
the `bootRepackage` task depend on that one using its `withJarTask` property:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
jar {
|
|
baseName = 'spring-boot-sample-profile'
|
|
version = '0.0.0'
|
|
excludes = ['**/application.yml']
|
|
}
|
|
|
|
task('execJar', type:Jar, dependsOn: 'jar') {
|
|
baseName = 'spring-boot-sample-profile'
|
|
version = '0.0.0'
|
|
classifier = 'exec'
|
|
from sourceSets.main.output
|
|
}
|
|
|
|
bootRepackage {
|
|
withJarTask = tasks['execJar']
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-remote-debug-maven-run]]
|
|
=== Remote debug a Spring Boot application started with Maven
|
|
To attach a remote debugger to a Spring Boot application started with Maven you can use
|
|
the `jvmArguments` property of the {spring-boot-maven-plugin-site}/[maven plugin].
|
|
|
|
Check {spring-boot-maven-plugin-site}/examples/run-debug.html[this example] for more details.
|
|
|
|
|
|
|
|
[[howto-remote-debug-gradle-run]]
|
|
=== Remote debug a Spring Boot application started with Gradle
|
|
To attach a remote debugger to a Spring Boot application started with Gradle you can use
|
|
the `jvmArgs` property of `bootRun` task or `--debug-jvm` command line option.
|
|
|
|
`build.gradle`:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
bootRun {
|
|
jvmArgs "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
|
|
}
|
|
----
|
|
|
|
|
|
Command line:
|
|
|
|
[indent=0]
|
|
----
|
|
$ gradle bootRun --debug-jvm
|
|
----
|
|
|
|
|
|
Check {gradle-userguide}/application_plugin.html[Gradle Application Plugin] for more
|
|
details.
|
|
|
|
|
|
|
|
[[howto-build-an-executable-archive-with-ant]]
|
|
=== Build an executable archive from Ant without using spring-boot-antlib
|
|
To build with Ant you need to grab dependencies, compile and then create a jar or war
|
|
archive. To make it executable you can either use the `spring-boot-antlib`
|
|
module, or you can follow these instructions:
|
|
|
|
. If you are building a jar, package the application's classes and resources in a nested
|
|
`BOOT-INF/classes` directory. If you are building a war, package the application's
|
|
classes in a nested `WEB-INF/classes` directory as usual.
|
|
. Add the runtime dependencies in a nested `BOOT-INF/lib` directory for a jar or
|
|
`WEB-INF/lib` for a war. Remember *not* to compress the entries in the archive.
|
|
. Add the `provided` (embedded container) dependencies in a nested `BOOT-INF/lib`
|
|
directory for jar or `WEB-INF/lib-provided` for a war. Remember *not* to compress the
|
|
entries in the archive.
|
|
. Add the `spring-boot-loader` classes at the root of the archive (so the `Main-Class`
|
|
is available).
|
|
. Use the appropriate launcher, e.g. `JarLauncher` for a jar file, as a `Main-Class`
|
|
attribute in the manifest and specify the other properties it needs as manifest entries,
|
|
principally a `Start-Class`.
|
|
|
|
Example:
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<target name="build" depends="compile">
|
|
<jar destfile="target/${ant.project.name}-${spring-boot.version}.jar" compress="false">
|
|
<mappedresources>
|
|
<fileset dir="target/classes" />
|
|
<globmapper from="*" to="BOOT-INF/classes/*"/>
|
|
</mappedresources>
|
|
<mappedresources>
|
|
<fileset dir="src/main/resources" erroronmissingdir="false"/>
|
|
<globmapper from="*" to="BOOT-INF/classes/*"/>
|
|
</mappedresources>
|
|
<mappedresources>
|
|
<fileset dir="${lib.dir}/runtime" />
|
|
<globmapper from="*" to="BOOT-INF/lib/*"/>
|
|
</mappedresources>
|
|
<zipfileset src="${lib.dir}/loader/spring-boot-loader-jar-${spring-boot.version}.jar" />
|
|
<manifest>
|
|
<attribute name="Main-Class" value="org.springframework.boot.loader.JarLauncher" />
|
|
<attribute name="Start-Class" value="${start-class}" />
|
|
</manifest>
|
|
</jar>
|
|
</target>
|
|
----
|
|
|
|
The {github-code}/spring-boot-samples/spring-boot-sample-ant[Ant Sample] has a
|
|
`build.xml` with a `manual` task that should work if you run it with
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
$ ant -lib <folder containing ivy-2.2.jar> clean manual
|
|
----
|
|
|
|
after which you can run the application with
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
$ java -jar target/*.jar
|
|
----
|
|
|
|
|
|
|
|
[[howto-use-java-6]]
|
|
=== How to use Java 6
|
|
If you want to use Spring Boot with Java 6 there are a small number of configuration
|
|
changes that you will have to make. The exact changes depend on your application's
|
|
functionality.
|
|
|
|
|
|
|
|
[[howto-use-java-6-embedded-container]]
|
|
==== Embedded servlet container compatibility
|
|
If you are using one of Boot's embedded Servlet containers you will have to use a
|
|
Java 6-compatible container. Both Tomcat 7 and Jetty 8 are Java 6 compatible. See
|
|
<<howto-use-tomcat-7>> and <<howto-use-jetty-8>> for details.
|
|
|
|
|
|
|
|
[[howto-use-java-6-jackson]]
|
|
==== Jackson
|
|
Jackson 2.7 and later requires Java 7. If you want to use Jackson with Java 6 you
|
|
will have to downgrade to Jackson 2.6.
|
|
|
|
|
|
|
|
[[how-to-use-java-6-jta-api]]
|
|
==== JTA API compatibility
|
|
While the Java Transaction API itself doesn't require Java 7 the official API jar
|
|
contains classes that have been built to require Java 7. If you are using JTA then
|
|
you will need to replace the official JTA 1.2 API jar with one that has been built
|
|
to work on Java 6. To do so, exclude any transitive dependencies on
|
|
`javax.transaction:javax.transaction-api` and replace them with a dependency on
|
|
`org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec:1.0.0.Final`
|
|
|
|
|
|
|
|
[[howto-traditional-deployment]]
|
|
== Traditional deployment
|
|
|
|
|
|
|
|
[[howto-create-a-deployable-war-file]]
|
|
=== Create a deployable war file
|
|
|
|
The first step in producing a deployable war file is to provide a
|
|
`SpringBootServletInitializer` subclass and override its `configure` method. This makes
|
|
use of Spring Framework's Servlet 3.0 support and allows you to configure your
|
|
application when it's launched by the servlet container. Typically, you update your
|
|
application's main class to extend `SpringBootServletInitializer`:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@SpringBootApplication
|
|
public class Application extends SpringBootServletInitializer {
|
|
|
|
@Override
|
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
|
return application.sources(Application.class);
|
|
}
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
SpringApplication.run(Application.class, args);
|
|
}
|
|
|
|
}
|
|
----
|
|
|
|
The next step is to update your build configuration so that your project produces a war file
|
|
rather than a jar file. If you're using Maven and using `spring-boot-starter-parent` (which
|
|
configures Maven's war plugin for you) all you need to do is modify `pom.xml` to change the
|
|
packaging to war:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<packaging>war</packaging>
|
|
----
|
|
|
|
If you're using Gradle, you need to modify `build.gradle` to apply the war plugin to the
|
|
project:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
apply plugin: 'war'
|
|
----
|
|
|
|
The final step in the process is to ensure that the embedded servlet container doesn't
|
|
interfere with the servlet container to which the war file will be deployed. To do so, you
|
|
need to mark the embedded servlet container dependency as provided.
|
|
|
|
If you're using Maven:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependencies>
|
|
<!-- … -->
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
|
<scope>provided</scope>
|
|
</dependency>
|
|
<!-- … -->
|
|
</dependencies>
|
|
----
|
|
|
|
And if you're using Gradle:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
dependencies {
|
|
// …
|
|
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
|
|
// …
|
|
}
|
|
----
|
|
|
|
NOTE: If you are using a version of Gradle that supports compile only dependencies (2.12
|
|
or later), you should continue to use `providedRuntime`. Among other limitations,
|
|
`compileOnly` dependencies are not on the test classpath so any web-based integration
|
|
tests will fail.
|
|
|
|
If you're using the <<build-tool-plugins.adoc#build-tool-plugins, Spring Boot build tools>>,
|
|
marking the embedded servlet container dependency as provided will produce an executable war
|
|
file with the provided dependencies packaged in a `lib-provided` directory. This means
|
|
that, in addition to being deployable to a servlet container, you can also run your
|
|
application using `java -jar` on the command line.
|
|
|
|
TIP: Take a look at Spring Boot's sample applications for a
|
|
{github-code}/spring-boot-samples/spring-boot-sample-traditional/pom.xml[Maven-based example]
|
|
of the above-described configuration.
|
|
|
|
|
|
|
|
[[howto-create-a-deployable-war-file-for-older-containers]]
|
|
=== Create a deployable war file for older servlet containers
|
|
Older Servlet containers don't have support for the `ServletContextInitializer` bootstrap
|
|
process used in Servlet 3.0. You can still use Spring and Spring Boot in these containers
|
|
but you are going to need to add a `web.xml` to your application and configure it to load
|
|
an `ApplicationContext` via a `DispatcherServlet`.
|
|
|
|
|
|
|
|
[[howto-convert-an-existing-application-to-spring-boot]]
|
|
=== Convert an existing application to Spring Boot
|
|
For a non-web application it should be easy (throw away the code that creates your
|
|
`ApplicationContext` and replace it with calls to `SpringApplication` or
|
|
`SpringApplicationBuilder`). Spring MVC web applications are generally amenable to first
|
|
creating a deployable war application, and then migrating it later to an executable war
|
|
and/or jar. Useful reading is in the https://spring.io/guides/gs/convert-jar-to-war/[Getting
|
|
Started Guide on Converting a jar to a war].
|
|
|
|
Create a deployable war by extending `SpringBootServletInitializer` (e.g. in a class
|
|
called `Application`), and add the Spring Boot `@SpringBootApplication` annotation.
|
|
Example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@SpringBootApplication
|
|
public class Application extends SpringBootServletInitializer {
|
|
|
|
@Override
|
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
|
// Customize the application or call application.sources(...) to add sources
|
|
// Since our example is itself a @Configuration class (via @SpringBootApplication)
|
|
// we actually don't need to override this method.
|
|
return application;
|
|
}
|
|
|
|
}
|
|
----
|
|
|
|
Remember that whatever you put in the `sources` is just a Spring `ApplicationContext` and
|
|
normally anything that already works should work here. There might be some beans you can
|
|
remove later and let Spring Boot provide its own defaults for them, but it should be
|
|
possible to get something working first.
|
|
|
|
Static resources can be moved to `/public` (or `/static` or `/resources` or
|
|
`/META-INF/resources`) in the classpath root. Same for `messages.properties` (Spring Boot
|
|
detects this automatically in the root of the classpath).
|
|
|
|
Vanilla usage of Spring `DispatcherServlet` and Spring Security should require no further
|
|
changes. If you have other features in your application, using other servlets or filters
|
|
for instance, then you may need to add some configuration to your `Application` context,
|
|
replacing those elements from the `web.xml` as follows:
|
|
|
|
* A `@Bean` of type `Servlet` or `ServletRegistrationBean` installs that bean in the
|
|
container as if it was a `<servlet/>` and `<servlet-mapping/>` in `web.xml`.
|
|
* A `@Bean` of type `Filter` or `FilterRegistrationBean` behaves similarly (like a
|
|
`<filter/>` and `<filter-mapping/>`.
|
|
* An `ApplicationContext` in an XML file can be added through an `@ImportResource` in
|
|
your `Application`. Or simple cases where annotation configuration is heavily used
|
|
already can be recreated in a few lines as `@Bean` definitions.
|
|
|
|
Once the war is working we make it executable by adding a `main` method to our
|
|
`Application`, e.g.
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
public static void main(String[] args) {
|
|
SpringApplication.run(Application.class, args);
|
|
}
|
|
----
|
|
|
|
[NOTE]
|
|
====
|
|
If you intend to start your application as a war or as an executable application, you
|
|
need to share the customizations of the builder in a method that is both available to the
|
|
`SpringBootServletInitializer` callback and the `main` method, something like:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@SpringBootApplication
|
|
public class Application extends SpringBootServletInitializer {
|
|
|
|
@Override
|
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
|
|
return configureApplication(builder);
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
configureApplication(new SpringApplicationBuilder()).run(args);
|
|
}
|
|
|
|
private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) {
|
|
return builder.sources(Application.class).bannerMode(Banner.Mode.OFF);
|
|
}
|
|
|
|
}
|
|
----
|
|
====
|
|
|
|
Applications can fall into more than one category:
|
|
|
|
* Servlet 3.0+ applications with no `web.xml`.
|
|
* Applications with a `web.xml`.
|
|
* Applications with a context hierarchy.
|
|
* Applications without a context hierarchy.
|
|
|
|
All of these should be amenable to translation, but each might require slightly different
|
|
tricks.
|
|
|
|
Servlet 3.0+ applications might translate pretty easily if they already use the Spring
|
|
Servlet 3.0+ initializer support classes. Normally all the code from an existing
|
|
`WebApplicationInitializer` can be moved into a `SpringBootServletInitializer`. If your
|
|
existing application has more than one `ApplicationContext` (e.g. if it uses
|
|
`AbstractDispatcherServletInitializer`) then you might be able to squash all your context
|
|
sources into a single `SpringApplication`. The main complication you might encounter is if
|
|
that doesn't work and you need to maintain the context hierarchy. See the
|
|
<<howto-build-an-application-context-hierarchy, entry on building a hierarchy>> for
|
|
examples. An existing parent context that contains web-specific features will usually
|
|
need to be broken up so that all the `ServletContextAware` components are in the child
|
|
context.
|
|
|
|
Applications that are not already Spring applications might be convertible to a Spring
|
|
Boot application, and the guidance above might help, but your mileage may vary.
|
|
|
|
|
|
|
|
[[howto-weblogic]]
|
|
=== Deploying a WAR to WebLogic
|
|
To deploy a Spring Boot application to WebLogic you must ensure that your servlet
|
|
initializer *directly* implements `WebApplicationInitializer` (even if you extend from a
|
|
base class that already implements it).
|
|
|
|
A typical initializer for WebLogic would be something like this:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
import org.springframework.boot.context.web.SpringBootServletInitializer;
|
|
import org.springframework.web.WebApplicationInitializer;
|
|
|
|
@SpringBootApplication
|
|
public class MyApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
|
|
|
|
}
|
|
----
|
|
|
|
If you use logback, you will also need to tell WebLogic to prefer the packaged version
|
|
rather than the version that pre-installed with the server. You can do this by adding a
|
|
`WEB-INF/weblogic.xml` file with the following contents:
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<wls:weblogic-web-app
|
|
xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
|
|
https://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd
|
|
http://xmlns.oracle.com/weblogic/weblogic-web-app
|
|
https://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
|
|
<wls:container-descriptor>
|
|
<wls:prefer-application-packages>
|
|
<wls:package-name>org.slf4j</wls:package-name>
|
|
</wls:prefer-application-packages>
|
|
</wls:container-descriptor>
|
|
</wls:weblogic-web-app>
|
|
----
|
|
|
|
|
|
|
|
[[howto-servlet-2-5]]
|
|
=== Deploying a WAR in an Old (Servlet 2.5) Container
|
|
Spring Boot uses Servlet 3.0 APIs to initialize the `ServletContext` (register `Servlets`
|
|
etc.) so you can't use the same application out of the box in a Servlet 2.5 container.
|
|
It *is* however possible to run a Spring Boot application on an older container with some
|
|
special tools. If you include `org.springframework.boot:spring-boot-legacy` as a
|
|
dependency (https://github.com/scratches/spring-boot-legacy[maintained separately] to the
|
|
core of Spring Boot and currently available at 1.0.2.RELEASE), all you should need to do
|
|
is create a `web.xml` and declare a context listener to create the application context and
|
|
your filters and servlets. The context listener is a special purpose one for Spring Boot,
|
|
but the rest of it is normal for a Spring application in Servlet 2.5. Example:
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
|
|
|
|
<context-param>
|
|
<param-name>contextConfigLocation</param-name>
|
|
<param-value>demo.Application</param-value>
|
|
</context-param>
|
|
|
|
<listener>
|
|
<listener-class>org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener</listener-class>
|
|
</listener>
|
|
|
|
<filter>
|
|
<filter-name>metricsFilter</filter-name>
|
|
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
|
</filter>
|
|
|
|
<filter-mapping>
|
|
<filter-name>metricsFilter</filter-name>
|
|
<url-pattern>/*</url-pattern>
|
|
</filter-mapping>
|
|
|
|
<servlet>
|
|
<servlet-name>appServlet</servlet-name>
|
|
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
|
<init-param>
|
|
<param-name>contextAttribute</param-name>
|
|
<param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
|
|
</init-param>
|
|
<load-on-startup>1</load-on-startup>
|
|
</servlet>
|
|
|
|
<servlet-mapping>
|
|
<servlet-name>appServlet</servlet-name>
|
|
<url-pattern>/</url-pattern>
|
|
</servlet-mapping>
|
|
|
|
</web-app>
|
|
----
|
|
|
|
In this example we are using a single application context (the one created by the context
|
|
listener) and attaching it to the `DispatcherServlet` using an init parameter. This is
|
|
normal in a Spring Boot application (you normally only have one application context).
|