@ -22,7 +22,7 @@ One way to run an unpacked archive is by starting the appropriate launcher, as f
@@ -22,7 +22,7 @@ One way to run an unpacked archive is by starting the appropriate launcher, as f
----
This is actually slightly faster on startup (depending on the size of the jar) than running from an unexploded archive.
At runtime you shouldn't expect any differences.
At runtime you should not expect any differences.
Once you have unpacked the jar file, you can also get an extra boost to startup time by running the app with its "natural" main method instead of the `JarLauncher`. For example:
@ -109,7 +109,7 @@ TIP: If you do not use Spring Data MongoDB, you can inject a `MongoClient` bean
@@ -109,7 +109,7 @@ TIP: If you do not use Spring Data MongoDB, you can inject a `MongoClient` bean
If you want to take complete control of establishing the MongoDB connection, you can also declare your own `MongoDatabaseFactory` or `MongoClient` bean.
NOTE: If you are using the reactive driver, Netty is required for SSL.
The auto-configuration configures this factory automatically if Netty is available and the factory to use hasn't been customized already.
The auto-configuration configures this factory automatically if Netty is available and the factory to use has not been customized already.
@ -140,7 +140,7 @@ Once the pre-stop hook has completed, SIGTERM will be sent to the container and
@@ -140,7 +140,7 @@ Once the pre-stop hook has completed, SIGTERM will be sent to the container and
NOTE: When Kubernetes sends a SIGTERM signal to the pod, it waits for a specified time called the termination grace period (the default for which is 30 seconds).
If the containers are still running after the grace period, they are sent the SIGKILL signal and forcibly removed.
If the pod takes longer than 30 seconds to shut down, which could be because you've increased configprop:spring.lifecycle.timeout-per-shutdown-phase[], make sure to increase the termination grace period by setting the `terminationGracePeriodSeconds` option in the Pod YAML.
If the pod takes longer than 30 seconds to shut down, which could be because you have increased configprop:spring.lifecycle.timeout-per-shutdown-phase[], make sure to increase the termination grace period by setting the `terminationGracePeriodSeconds` option in the Pod YAML.
@ -119,7 +119,7 @@ Firstly, configure its permissions so that it cannot be written and can only be
@@ -119,7 +119,7 @@ Firstly, configure its permissions so that it cannot be written and can only be
$ chmod 500 your-app.jar
----
Second, you should also take steps to limit the damage if your application or the account that's running it is compromised.
Second, you should also take steps to limit the damage if your application or the account that is running it is compromised.
If an attacker does gain access, they could make the jar file writable and change its contents.
One way to protect against this is to make it immutable by using `chattr`, as shown in the following example:
@ -286,7 +286,7 @@ The following property substitutions are supported with the default script:
@@ -286,7 +286,7 @@ The following property substitutions are supported with the default script:
|
| `useStartStopDaemon`
| Whether the `start-stop-daemon` command, when it's available, should be used to control the process
| Whether the `start-stop-daemon` command, when it is available, should be used to control the process
| `true`
| `true`
@ -319,7 +319,7 @@ The following environment properties are supported with the default script:
@@ -319,7 +319,7 @@ The following environment properties are supported with the default script:
When not set, the user that owns the jar file will be used.
| `USE_START_STOP_DAEMON`
| Whether the `start-stop-daemon` command, when it's available, should be used to control the process.
| Whether the `start-stop-daemon` command, when it is available, should be used to control the process.
@ -108,7 +108,7 @@ The only difference between using these conditions at the class level and markin
@@ -108,7 +108,7 @@ The only difference between using these conditions at the class level and markin
TIP: When declaring a `@Bean` method, provide as much type information as possible in the method's return type.
For example, if your bean's concrete class implements an interface the bean method's return type should be the concrete class and not the interface.
Providing as much type information as possible in `@Bean` methods is particularly important when using bean conditions as their evaluation can only rely upon to type information that's available in the method signature.
Providing as much type information as possible in `@Bean` methods is particularly important when using bean conditions as their evaluation can only rely upon to type information that is available in the method signature.
@ -134,7 +134,7 @@ The following example shows how to specify two distinct files:
@@ -134,7 +134,7 @@ The following example shows how to specify two distinct files:
optional:classpath:/override.properties
----
TIP: Use the prefix `optional:` if the <<features#features.external-config.files.optional-prefix,locations are optional>> and you don't mind if they don't exist.
TIP: Use the prefix `optional:` if the <<features#features.external-config.files.optional-prefix,locations are optional>> and you do not mind if they do not exist.
WARNING: `spring.config.name`, `spring.config.location`, and `spring.config.additional-location` are used very early to determine which files have to be loaded.
They must be defined as an environment property (typically an OS environment variable, a system property, or a command-line argument).
@ -186,7 +186,7 @@ NOTE: If your application runs in a servlet container or application server, the
@@ -186,7 +186,7 @@ NOTE: If your application runs in a servlet container or application server, the
==== Optional Locations
By default, when a specified config data location does not exist, Spring Boot will throw a `ConfigDataLocationNotFoundException` and your application will not start.
If you want to specify a location, but you don't mind if it doesn't always exist, you can use the `optional:` prefix.
If you want to specify a location, but you do not mind if it does not always exist, you can use the `optional:` prefix.
You can use this prefix with the `spring.config.location` and `spring.config.additional-location` properties, as well as with <<features#features.external-config.files.importing, `spring.config.import`>> declarations.
For example, a `spring.config.import` value of `optional:file:./myconfig.properties` allows your application to start, even if the `myconfig.properties` file is missing.
@ -261,7 +261,7 @@ The `Environment` has a set of default profiles (by default, `[default]`) that a
@@ -261,7 +261,7 @@ The `Environment` has a set of default profiles (by default, `[default]`) that a
In other words, if no profiles are explicitly activated, then properties from `application-default` are considered.
NOTE: Properties files are only ever loaded once.
If you've already directly <<features#features.external-config.files.importing,imported>> a profile specific property files then it won't be imported a second time.
If you have already directly <<features#features.external-config.files.importing,imported>> a profile specific property files then it will not be imported a second time.
@ -286,7 +286,7 @@ Values from the imported `dev.properties` will take precedence over the file tha
@@ -286,7 +286,7 @@ Values from the imported `dev.properties` will take precedence over the file tha
In the above example, the `dev.properties` could redefine `spring.application.name` to a different value.
An import will only be imported once no matter how many times it is declared.
The order an import is defined inside a single document within the properties/yaml file doesn't matter.
The order an import is defined inside a single document within the properties/yaml file does not matter.
For instance, the two examples below produce the same result:
@ -320,7 +320,7 @@ The example above would import both `my.properties` as well as any `my-<profile>
@@ -320,7 +320,7 @@ The example above would import both `my.properties` as well as any `my-<profile>
Spring Boot includes pluggable API that allows various different location addresses to be supported.
By default you can import Java Properties, YAML and "`<<features#features.external-config.files.configtree, configuration trees>>`".
Third-party jars can offer support for additional technologies (there's no requirement for files to be local).
Third-party jars can offer support for additional technologies (there is no requirement for files to be local).
For example, you can imagine config data being from external stores such as Consul, Apache ZooKeeper or Netflix Archaius.
If you want to support your own locations, see the `ConfigDataLocationResolver` and `ConfigDataLoader` classes in the `org.springframework.boot.context.config` package.
@ -349,7 +349,7 @@ You can import it from your `application.properties` using the following:
@@ -349,7 +349,7 @@ You can import it from your `application.properties` using the following:
[[features.external-config.files.configtree]]
==== Using Configuration Trees
When running applications on a cloud platform (such as Kubernetes) you often need to read config values that the platform supplies.
It's not uncommon to use environment variables for such purposes, but this can have drawbacks, especially if the value is supposed to be kept secret.
It is not uncommon to use environment variables for such purposes, but this can have drawbacks, especially if the value is supposed to be kept secret.
As an alternative to environment variables, many cloud platforms now allow you to map configuration into mounted data volumes.
For example, Kubernetes can volume mount both https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#populate-a-volume-with-data-stored-in-a-configmap[`ConfigMaps`] and https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod[`Secrets`].
@ -495,7 +495,7 @@ WARNING: Multi-document property files cannot be loaded by using the `@PropertyS
@@ -495,7 +495,7 @@ WARNING: Multi-document property files cannot be loaded by using the `@PropertyS
It's sometimes useful to only activate a given get of properties when certain conditions are met.
It is sometimes useful to only activate a given get of properties when certain conditions are met.
For example, you might have properties that are only relevant when a specific profile is active.
You can conditionally activate a properties document using `spring.config.activate.*`.
@ -903,7 +903,7 @@ For example, consider binding the following properties to a `Map<String,String>`
@@ -903,7 +903,7 @@ For example, consider binding the following properties to a `Map<String,String>`
NOTE: For YAML files, the brackets need to be surrounded by quotes for the keys to be parsed properly.
The properties above will bind to a `Map` with `/key1`, `/key2` and `key3` as the keys in the map.
The slash has been removed from `key3` because it wasn't surrounded by square brackets.
The slash has been removed from `key3` because it was not surrounded by square brackets.
You may also occasionally need to use the bracket notation if your `key` contains a `.` and you are binding to non-scalar value.
For example, binding `a.b=c` to `Map<String, Object>` will return a Map with the entry `{"a"={"b"="c"}}` whereas `[a.b]=c` will return a Map with the entry `{"a.b"="c"}`.
TIP: If you are upgrading a `Long` property, make sure to define the unit (using `@DurationUnit`) if it isn't milliseconds.
TIP: If you are upgrading a `Long` property, make sure to define the unit (using `@DurationUnit`) if it is not milliseconds.
Doing so gives a transparent upgrade path while supporting a much richer format.
@ -1142,7 +1142,7 @@ If you prefer to use constructor binding, the same properties can be exposed, as
@@ -1142,7 +1142,7 @@ If you prefer to use constructor binding, the same properties can be exposed, as
@ -161,8 +161,8 @@ As a result, specific configuration keys (such as `logback.configurationFile` fo
@@ -161,8 +161,8 @@ As a result, specific configuration keys (such as `logback.configurationFile` fo
[[features.logging.file-rotation]]
=== File Rotation
If you are using the Logback, it's possible to fine-tune log rotation settings using your `application.properties` or `application.yaml` file.
For all other logging system, you'll need to configure rotation settings directly yourself (for example, if you use Log4J2 then you could add a `log4j.xml` file).
If you are using the Logback, it is possible to fine-tune log rotation settings using your `application.properties` or `application.yaml` file.
For all other logging system, you will need to configure rotation settings directly yourself (for example, if you use Log4J2 then you could add a `log4j.xml` file).
The following rotation policy properties are supported:
@ -176,7 +176,7 @@ The following rotation policy properties are supported:
@@ -176,7 +176,7 @@ The following rotation policy properties are supported:
| If log archive cleanup should occur when the application starts.
| The maximum amount of size log archives can take before being deleted.
@ -212,22 +212,22 @@ The following example shows potential logging settings in `application.propertie
@@ -212,22 +212,22 @@ The following example shows potential logging settings in `application.propertie
org.hibernate: "error"
----
It's also possible to set logging levels using environment variables.
It is also possible to set logging levels using environment variables.
For example, `LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUG` will set `org.springframework.web` to `DEBUG`.
NOTE: The above approach will only work for package level logging.
Since relaxed binding always converts environment variables to lowercase, it's not possible to configure logging for an individual class in this way.
Since relaxed binding always converts environment variables to lowercase, it is not possible to configure logging for an individual class in this way.
If you need to configure logging for a class, you can use <<features#features.external-config.application-json, the `SPRING_APPLICATION_JSON`>> variable.
[[features.logging.log-groups]]
=== Log Groups
It's often useful to be able to group related loggers together so that they can all be configured at the same time.
For example, you might commonly change the logging levels for _all_ Tomcat related loggers, but you can't easily remember top level packages.
It is often useful to be able to group related loggers together so that they can all be configured at the same time.
For example, you might commonly change the logging levels for _all_ Tomcat related loggers, but you can not easily remember top level packages.
To help with this, Spring Boot allows you to define logging groups in your Spring `Environment`.
For example, here's how you could define a "`tomcat`" group by adding it to your `application.properties`:
For example, here is how you could define a "`tomcat`" group by adding it to your `application.properties`:
@ -61,7 +61,7 @@ For instance, if you start a web application on port `8080` and that port is alr
@@ -61,7 +61,7 @@ For instance, if you start a web application on port `8080` and that port is alr
Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
Identify and stop the process that is listening on port 8080 or configure this application to listen on another port.
----
NOTE: Spring Boot provides numerous `FailureAnalyzer` implementations, and you can <<howto#howto.application.failure-analyzer,add your own>>.
@ -152,7 +152,7 @@ The printed banner is registered as a singleton bean under the following name: `
@@ -152,7 +152,7 @@ The printed banner is registered as a singleton bean under the following name: `
[NOTE]
====
The `${application.version}` and `${application.formatted-version}` properties are only available if you are using Spring Boot launchers.
The values won't be resolved if you are running an unpacked jar and starting it with `java -cp <classpath> <mainclass>`.
The values will not be resolved if you are running an unpacked jar and starting it with `java -cp <classpath> <mainclass>`.
This is why we recommend that you always launch unpacked jars using `java org.springframework.boot.loader.JarLauncher`.
This will initialize the `application.*` banner variables before building the classpath and launching your app.
@ -209,7 +209,7 @@ In addition, you can also obtain availability states by injecting the `Applicati
@@ -209,7 +209,7 @@ In addition, you can also obtain availability states by injecting the `Applicati
The "`Liveness`" state of an application tells whether its internal state allows it to work correctly, or recover by itself if it's currently failing.
The "`Liveness`" state of an application tells whether its internal state allows it to work correctly, or recover by itself if it is currently failing.
A broken "`Liveness`" state means that the application is in a state that it cannot recover from, and the infrastructure should restart the application.
NOTE: In general, the "Liveness" state should not be based on external checks, such as <<actuator#actuator.endpoints.health, Health checks>>.
@ -225,7 +225,7 @@ An application is considered live as soon as the context has been refreshed, see
@@ -225,7 +225,7 @@ An application is considered live as soon as the context has been refreshed, see
==== Readiness State
The "`Readiness`" state of an application tells whether the application is ready to handle traffic.
A failing "`Readiness`" state tells the platform that it should not route traffic to the application for now.
This typically happens during startup, while `CommandLineRunner` and `ApplicationRunner` components are being processed, or at any time if the application decides that it's too busy for additional traffic.
This typically happens during startup, while `CommandLineRunner` and `ApplicationRunner` components are being processed, or at any time if the application decides that it is too busy for additional traffic.
An application is considered ready as soon as application and command-line runners have been called, see <<features#features.spring-application.application-events-and-listeners, Spring Boot application lifecycle and related Application Events>>.
@ -73,8 +73,8 @@ Spring Boot provides a `@SpringBootTest` annotation, which can be used as an alt
@@ -73,8 +73,8 @@ Spring Boot provides a `@SpringBootTest` annotation, which can be used as an alt
The annotation works by <<features#features.testing.spring-boot-applications.detecting-configuration,creating the `ApplicationContext` used in your tests through `SpringApplication`>>.
In addition to `@SpringBootTest` a number of other annotations are also provided for <<features#features.testing.spring-boot-applications.autoconfigured-tests,testing more specific slices>> of an application.
TIP: If you are using JUnit 4, don't forget to also add `@RunWith(SpringRunner.class)` to your test, otherwise the annotations will be ignored.
If you are using JUnit 5, there's no need to add the equivalent `@ExtendWith(SpringExtension.class)` as `@SpringBootTest` and the other `@...Test` annotations are already annotated with it.
TIP: If you are using JUnit 4, do not forget to also add `@RunWith(SpringRunner.class)` to your test, otherwise the annotations will be ignored.
If you are using JUnit 5, there is no need to add the equivalent `@ExtendWith(SpringExtension.class)` as `@SpringBootTest` and the other `@...Test` annotations are already annotated with it.
By default, `@SpringBootTest` will not start a server.
You can use the `webEnvironment` attribute of `@SpringBootTest` to further refine how your tests run:
@ -100,7 +100,7 @@ NOTE: `@SpringBootTest` with `webEnvironment = WebEnvironment.RANDOM_PORT` will
@@ -100,7 +100,7 @@ NOTE: `@SpringBootTest` with `webEnvironment = WebEnvironment.RANDOM_PORT` will
TIP: `WebTestClient` can be used against both live servers and <<features#features.testing.spring-boot-applications.with-mock-environment, mock environments>>.
This setup requires `spring-webflux` on the classpath.
If you can't or won't add webflux, Spring Boot also provides a `TestRestTemplate` facility:
If you can not or will not add webflux, Spring Boot also provides a `TestRestTemplate` facility:
[source,java,indent=0,subs="verbatim"]
----
@ -285,7 +285,7 @@ The following example replaces an existing `RemoteService` bean with a mock impl
@@ -285,7 +285,7 @@ The following example replaces an existing `RemoteService` bean with a mock impl
@ -62,7 +62,7 @@ Alternatively, additional patterns can be configured using configprop:management
@@ -62,7 +62,7 @@ Alternatively, additional patterns can be configured using configprop:management
Spring Boot health indicators return a `Status` type to indicate the overall system health.
If you want to monitor or alert on levels of health for a particular application, you can export these statuses as metrics via Micrometer.
By default, the status codes "`UP`", "`DOWN`", "`OUT_OF_SERVICE`" and "`UNKNOWN`" are used by Spring Boot.
To export these, you'll need to convert these states to some set of numbers so that they can be used with a Micrometer `Gauge`.
To export these, you will need to convert these states to some set of numbers so that they can be used with a Micrometer `Gauge`.
The following example shows one way to write such an exporter:
@ -32,7 +32,7 @@ The following example shows how to define a data source by setting properties:
@@ -32,7 +32,7 @@ The following example shows how to define a data source by setting properties:
Assuming that `SomeDataSource` has regular JavaBean properties for the URL, the username, and the pool size, these settings are bound automatically before the `DataSource` is made available to other components.
Spring Boot also provides a utility builder class, called `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.
The builder can detect the one to use based on what is available on the classpath.
It also auto-detects the driver based on the JDBC URL.
The following example shows how to create a data source by using a `DataSourceBuilder`:
@ -36,7 +36,7 @@ By default, Spring Boot picks up the native configuration from its default locat
@@ -36,7 +36,7 @@ By default, Spring Boot picks up the native configuration from its default locat
[[howto.logging.logback]]
=== Configure Logback for Logging
If you need to apply customizations to logback beyond those that can be achieved with `application.properties`, you'll need to add a standard logback configuration file.
If you need to apply customizations to logback beyond those that can be achieved with `application.properties`, you will need to add a standard logback configuration file.
You can add a `logback.xml` file to the root of your classpath for logback to find.
You can also use `logback-spring.xml` if you want to use the <<features#features.logging.logback-extensions,Spring Boot Logback extensions>>.
@ -238,7 +238,7 @@ The `server.{asterisk}` namespace is quite useful here, and it includes namespac
@@ -238,7 +238,7 @@ The `server.{asterisk}` namespace is quite useful here, and it includes namespac
See the list of <<application-properties#application-properties>>.
The previous sections covered already many common use cases, such as compression, SSL or HTTP/2.
However, if a configuration key doesn't exist for your use case, you should then look at {spring-boot-module-api}/web/server/WebServerFactoryCustomizer.html[`WebServerFactoryCustomizer`].
However, if a configuration key does not exist for your use case, you should then look at {spring-boot-module-api}/web/server/WebServerFactoryCustomizer.html[`WebServerFactoryCustomizer`].
You can declare such a component and get access to the server factory relevant to your choice: you should select the variant for the chosen Server (Tomcat, Jetty, Reactor Netty, Undertow) and the chosen web stack (servlet or reactive).
The example below is for Tomcat with the `spring-boot-starter-web` (servlet stack):
NOTE: Spring Boot uses that infrastructure internally to auto-configure the server.
Auto-configured `WebServerFactoryCustomizer` beans have an order of `0` and will be processed before any user-defined customizers, unless it has an explicit order that states otherwise.
Once you've got access to a `WebServerFactory` using the customizer, you can use it to configure specific parts, like connectors, server resources, or the server itself - all using server-specific APIs.
Once you have got access to a `WebServerFactory` using the customizer, you can use it to configure specific parts, like connectors, server resources, or the server itself - all using server-specific APIs.
Most applications will need to deal with input and output concerns at some point.
Spring Boot provides utilities and integrations with a range of technologies to help when you need IO capabilities.
This section covers standard IO features such as caching and validation as well as more advanced topics such as scheduling and distributed transactions.
We'll also cover calling remote REST or SOAP services and sending email.
We will also cover calling remote REST or SOAP services and sending email.
@ -13,7 +13,7 @@ Spring Boot first attempts to create a client by checking the following configur
@@ -13,7 +13,7 @@ Spring Boot first attempts to create a client by checking the following configur
NOTE: Spring Boot supports both Hazelcast 4 and Hazelcast 3.
If you downgrade to Hazelcast 3, `hazelcast-client` should be added to the classpath to configure a client.
If a client can't be created, Spring Boot attempts to configure an embedded server.
If a client can not be created, Spring Boot attempts to configure an embedded server.
If you define a `com.hazelcast.config.Config` bean, Spring Boot uses that.
If your configuration defines an instance name, Spring Boot tries to locate an existing instance rather than creating a new one.
@ -76,7 +76,7 @@ As a client, you need to configure and establish an RSocket connection first.
@@ -76,7 +76,7 @@ As a client, you need to configure and establish an RSocket connection first.
Spring Boot auto-configures an `RSocketRequester.Builder` for such cases with the expected codecs and applies any `RSocketConnectorConfigurer` bean.
The `RSocketRequester.Builder` instance is a prototype bean, meaning each injection point will provide you with a new instance .
This is done on purpose since this builder is stateful and you shouldn't create requesters with different setups using the same instance.
This is done on purpose since this builder is stateful and you should not create requesters with different setups using the same instance.
@ -113,7 +113,7 @@ For example, if you want to get started using Spring and JPA for database access
@@ -113,7 +113,7 @@ For example, if you want to get started using Spring and JPA for database access
The starters contain a lot of the dependencies that you need to get a project up and running quickly and with a consistent, supported set of managed transitive dependencies.
.What's in a name
.What is in a name
****
All **official** starters follow a similar naming pattern; `+spring-boot-starter-*+`, where `+*+` is a particular type of application.
This naming structure is intended to help when you need to find a starter.
@ -57,7 +57,7 @@ Because you need more information about web requests while developing Spring MVC
@@ -57,7 +57,7 @@ Because you need more information about web requests while developing Spring MVC
This will give you information about the incoming request, which handler is processing it, the response outcome, etc.
If you wish to log all request details (including potentially sensitive information), you can turn on the configprop:spring.mvc.log-request-details[] or configprop:spring.codec.log-request-details[] configuration properties.
NOTE: If you don't want property defaults to be applied you can set configprop:spring.devtools.add-properties[] to `false` in your `application.properties`.
NOTE: If you do not want property defaults to be applied you can set configprop:spring.devtools.add-properties[] to `false` in your `application.properties`.
TIP: For a complete list of the properties that are applied by the devtools, see {spring-boot-devtools-module-code}/env/DevToolsPropertyDefaultsPostProcessor.java[DevToolsPropertyDefaultsPostProcessor].
@ -13,7 +13,7 @@ The following example shows a `@Service` Bean that uses constructor injection to
@@ -13,7 +13,7 @@ The following example shows a `@Service` Bean that uses constructor injection to
@ -22,7 +22,7 @@ The <<using#using.using-the-springbootapplication-annotation, `@SpringBootApplic
@@ -22,7 +22,7 @@ The <<using#using.using-the-springbootapplication-annotation, `@SpringBootApplic
For example, if you are writing a JPA application, the package of the `@SpringBootApplication` annotated class is used to search for `@Entity` items.
Using a root package also allows component scan to apply only on your project.
TIP: If you don't want to use `@SpringBootApplication`, the `@EnableAutoConfiguration` and `@ComponentScan` annotations that it imports defines that behavior so you can also use those instead.
TIP: If you do not want to use `@SpringBootApplication`, the `@EnableAutoConfiguration` and `@ComponentScan` annotations that it imports defines that behavior so you can also use those instead.
@ -203,12 +203,12 @@ If either is found, it is automatically used as the welcome page of the applicat
@@ -203,12 +203,12 @@ If either is found, it is automatically used as the welcome page of the applicat
==== Path Matching and Content Negotiation
Spring MVC can map incoming HTTP requests to handlers by looking at the request path and matching it to the mappings defined in your application (for example, `@GetMapping` annotations on Controller methods).
Spring Boot chooses to disable suffix pattern matching by default, which means that requests like `"GET /projects/spring-boot.json"` won't be matched to `@GetMapping("/projects/spring-boot")` mappings.
Spring Boot chooses to disable suffix pattern matching by default, which means that requests like `"GET /projects/spring-boot.json"` will not be matched to `@GetMapping("/projects/spring-boot")` mappings.
This is considered as a {spring-framework-docs}/web.html#mvc-ann-requestmapping-suffix-pattern-match[best practice for Spring MVC applications].
This feature was mainly useful in the past for HTTP clients which did not send proper "Accept" request headers; we needed to make sure to send the correct Content Type to the client.
Nowadays, Content Negotiation is much more reliable.
There are other ways to deal with HTTP clients that don't consistently send proper "Accept" request headers.
There are other ways to deal with HTTP clients that do not consistently send proper "Accept" request headers.
Instead of using suffix matching, we can use a query parameter to ensure that requests like `"GET /projects/spring-boot?format=json"` will be mapped to `@GetMapping("/projects/spring-boot")`:
@ -256,7 +256,7 @@ If you understand the caveats and would still like your application to use suffi
@@ -256,7 +256,7 @@ If you understand the caveats and would still like your application to use suffi
use-suffix-pattern: true
----
Alternatively, rather than open all suffix patterns, it's more secure to only support registered suffix patterns:
Alternatively, rather than open all suffix patterns, it is more secure to only support registered suffix patterns:
@ -28,7 +28,7 @@ public class MyApplication extends SpringBootServletInitializer {
@@ -28,7 +28,7 @@ public class MyApplication extends SpringBootServletInitializer {