From 6bc196883a2bd9a04d7ce62dd97f5f45634e0024 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Fri, 11 Apr 2025 17:39:38 +0200 Subject: [PATCH 1/4] Fix heading for "Context Configuration with Context Customizers" --- .../ctx-management/context-customizers.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc index 1698c61692..f1af4efc3c 100644 --- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc +++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc @@ -1,5 +1,5 @@ [[testcontext-context-customizers]] -= Configuration Configuration with Context Customizers += Context Configuration with Context Customizers A `ContextCustomizer` is responsible for customizing the supplied `ConfigurableApplicationContext` after bean definitions have been loaded into the context From f27382cfb6af887360d0e0f3be2bd3b77fa48eb9 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Fri, 11 Apr 2025 17:41:04 +0200 Subject: [PATCH 2/4] Consistently indent code with tabs in reference manual --- .../modules/ROOT/pages/core/aot.adoc | 16 +- .../annotation-config/value-annotations.adoc | 84 ++--- .../modules/ROOT/pages/core/beans/basics.adoc | 14 +- .../core/beans/context-introduction.adoc | 2 +- .../pages/core/beans/factory-extension.adoc | 2 +- .../modules/ROOT/pages/core/spring-jcl.adoc | 6 +- .../jdbc/embedded-database-support.adoc | 38 +-- .../modules/ROOT/pages/data-access/r2dbc.adoc | 72 ++--- .../modules/ROOT/pages/integration/cds.adoc | 10 +- .../ROOT/pages/integration/rest-clients.adoc | 295 +++++++++--------- .../pages/languages/kotlin/coroutines.adoc | 48 ++- .../languages/kotlin/spring-projects-in.adoc | 106 ++++--- .../ROOT/pages/languages/kotlin/web.adoc | 109 +++---- .../mockmvc/hamcrest/async-requests.adoc | 18 +- .../ROOT/pages/testing/webtestclient.adoc | 2 +- .../web/webflux-webclient/client-body.adoc | 42 +-- .../web/webflux-webclient/client-builder.adoc | 26 +- .../web/webflux-webclient/client-filter.adoc | 110 +++---- .../ROOT/pages/web/webflux-websocket.adoc | 10 +- .../ROOT/pages/web/webflux/config.adoc | 2 +- .../ann-methods/modelattrib-method-args.adoc | 2 +- .../controller/ann-modelattrib-methods.adoc | 4 +- .../webflux/controller/ann-validation.adoc | 8 +- .../pages/web/webflux/reactive-spring.adoc | 8 +- .../ROOT/pages/web/webmvc-functional.adoc | 12 +- .../ann-methods/modelattrib-method-args.adoc | 2 +- .../webmvc/mvc-controller/ann-validation.adoc | 22 +- .../pages/web/websocket/stomp/enable.adoc | 12 +- 28 files changed, 537 insertions(+), 545 deletions(-) diff --git a/framework-docs/modules/ROOT/pages/core/aot.adoc b/framework-docs/modules/ROOT/pages/core/aot.adoc index 80a75965d7..ce75e7fa59 100644 --- a/framework-docs/modules/ROOT/pages/core/aot.adoc +++ b/framework-docs/modules/ROOT/pages/core/aot.adoc @@ -469,20 +469,20 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- - RootBeanDefinition beanDefinition = new RootBeanDefinition(ClientFactoryBean.class); - beanDefinition.setTargetType(ResolvableType.forClassWithGenerics(ClientFactoryBean.class, MyClient.class)); - // ... - registry.registerBeanDefinition("myClient", beanDefinition); + RootBeanDefinition beanDefinition = new RootBeanDefinition(ClientFactoryBean.class); + beanDefinition.setTargetType(ResolvableType.forClassWithGenerics(ClientFactoryBean.class, MyClient.class)); + // ... + registry.registerBeanDefinition("myClient", beanDefinition); ---- Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- - val beanDefinition = RootBeanDefinition(ClientFactoryBean::class.java) - beanDefinition.setTargetType(ResolvableType.forClassWithGenerics(ClientFactoryBean::class.java, MyClient::class.java)); - // ... - registry.registerBeanDefinition("myClient", beanDefinition) + val beanDefinition = RootBeanDefinition(ClientFactoryBean::class.java) + beanDefinition.setTargetType(ResolvableType.forClassWithGenerics(ClientFactoryBean::class.java, MyClient::class.java)); + // ... + registry.registerBeanDefinition("myClient", beanDefinition) ---- ====== diff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/value-annotations.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/value-annotations.adoc index 13f20afe73..72e70005d0 100644 --- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/value-annotations.adoc +++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/value-annotations.adoc @@ -9,15 +9,15 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- - @Component - public class MovieRecommender { + @Component + public class MovieRecommender { - private final String catalog; + private final String catalog; - public MovieRecommender(@Value("${catalog.name}") String catalog) { - this.catalog = catalog; - } - } + public MovieRecommender(@Value("${catalog.name}") String catalog) { + this.catalog = catalog; + } + } ---- Kotlin:: @@ -37,9 +37,9 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- - @Configuration - @PropertySource("classpath:application.properties") - public class AppConfig { } + @Configuration + @PropertySource("classpath:application.properties") + public class AppConfig { } ---- Kotlin:: @@ -56,7 +56,7 @@ And the following `application.properties` file: [source,java,indent=0,subs="verbatim,quotes"] ---- - catalog.name=MovieCatalog + catalog.name=MovieCatalog ---- In that case, the `catalog` parameter and field will be equal to the `MovieCatalog` value. @@ -119,15 +119,15 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- - @Component - public class MovieRecommender { + @Component + public class MovieRecommender { - private final String catalog; + private final String catalog; - public MovieRecommender(@Value("${catalog.name:defaultCatalog}") String catalog) { - this.catalog = catalog; - } - } + public MovieRecommender(@Value("${catalog.name:defaultCatalog}") String catalog) { + this.catalog = catalog; + } + } ---- Kotlin:: @@ -150,16 +150,16 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- - @Configuration - public class AppConfig { + @Configuration + public class AppConfig { - @Bean - public ConversionService conversionService() { - DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(); - conversionService.addConverter(new MyCustomConverter()); - return conversionService; - } - } + @Bean + public ConversionService conversionService() { + DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(); + conversionService.addConverter(new MyCustomConverter()); + return conversionService; + } + } ---- Kotlin:: @@ -188,15 +188,15 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- - @Component - public class MovieRecommender { + @Component + public class MovieRecommender { - private final String catalog; + private final String catalog; - public MovieRecommender(@Value("#{systemProperties['user.catalog'] + 'Catalog' }") String catalog) { - this.catalog = catalog; - } - } + public MovieRecommender(@Value("#{systemProperties['user.catalog'] + 'Catalog' }") String catalog) { + this.catalog = catalog; + } + } ---- Kotlin:: @@ -217,16 +217,16 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- - @Component - public class MovieRecommender { + @Component + public class MovieRecommender { - private final Map countOfMoviesPerCatalog; + private final Map countOfMoviesPerCatalog; - public MovieRecommender( - @Value("#{{'Thriller': 100, 'Comedy': 300}}") Map countOfMoviesPerCatalog) { - this.countOfMoviesPerCatalog = countOfMoviesPerCatalog; - } - } + public MovieRecommender( + @Value("#{{'Thriller': 100, 'Comedy': 300}}") Map countOfMoviesPerCatalog) { + this.countOfMoviesPerCatalog = countOfMoviesPerCatalog; + } + } ---- Kotlin:: diff --git a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc index 8c4697771a..4d209d1b72 100644 --- a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc +++ b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc @@ -119,7 +119,7 @@ Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- - val context = ClassPathXmlApplicationContext("services.xml", "daos.xml") + val context = ClassPathXmlApplicationContext("services.xml", "daos.xml") ---- ====== @@ -310,16 +310,16 @@ Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- - import org.springframework.beans.factory.getBean + import org.springframework.beans.factory.getBean // create and configure beans - val context = ClassPathXmlApplicationContext("services.xml", "daos.xml") + val context = ClassPathXmlApplicationContext("services.xml", "daos.xml") - // retrieve configured instance - val service = context.getBean("petStore") + // retrieve configured instance + val service = context.getBean("petStore") - // use configured instance - var userList = service.getUsernameList() + // use configured instance + var userList = service.getUsernameList() ---- ====== diff --git a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc index 612185813e..537b90cc5f 100644 --- a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc +++ b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc @@ -513,7 +513,7 @@ the classes above: - + diff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc index cf9e68e3a8..bd4f6da550 100644 --- a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc +++ b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc @@ -226,7 +226,7 @@ Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- - import org.springframework.beans.factory.getBean + import org.springframework.beans.factory.getBean fun main() { val ctx = ClassPathXmlApplicationContext("scripting/beans.xml") diff --git a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc index 547b80ddd4..2dd0ed4748 100644 --- a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc +++ b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc @@ -31,7 +31,7 @@ Java:: ---- public class MyBean { private final Log log = LogFactory.getLog(getClass()); - // ... + // ... } ---- @@ -40,8 +40,8 @@ Kotlin:: [source,kotlin,indent=0,subs="verbatim,quotes"] ---- class MyBean { - private val log = LogFactory.getLog(javaClass) - // ... + private val log = LogFactory.getLog(javaClass) + // ... } ---- ====== diff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc index 96a6023dac..83ccd98d84 100644 --- a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc +++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc @@ -78,27 +78,27 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- - @Configuration - public class DataSourceConfig { + @Configuration + public class DataSourceConfig { - @Bean - public DataSource dataSource() { - return new EmbeddedDatabaseBuilder() - .setDatabaseConfigurer(EmbeddedDatabaseConfigurers - .customizeConfigurer(H2, this::customize)) - .addScript("schema.sql") - .build(); - } + @Bean + public DataSource dataSource() { + return new EmbeddedDatabaseBuilder() + .setDatabaseConfigurer(EmbeddedDatabaseConfigurers + .customizeConfigurer(H2, this::customize)) + .addScript("schema.sql") + .build(); + } - private EmbeddedDatabaseConfigurer customize(EmbeddedDatabaseConfigurer defaultConfigurer) { - return new EmbeddedDatabaseConfigurerDelegate(defaultConfigurer) { - @Override - public void configureConnectionProperties(ConnectionProperties properties, String databaseName) { - super.configureConnectionProperties(properties, databaseName); - properties.setDriverClass(CustomDriver.class); - } - }; - } + private EmbeddedDatabaseConfigurer customize(EmbeddedDatabaseConfigurer defaultConfigurer) { + return new EmbeddedDatabaseConfigurerDelegate(defaultConfigurer) { + @Override + public void configureConnectionProperties(ConnectionProperties properties, String databaseName) { + super.configureConnectionProperties(properties, databaseName); + properties.setDriverClass(CustomDriver.class); + } + }; + } } ---- diff --git a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc index c27fd7ec45..086562d73b 100644 --- a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc +++ b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc @@ -136,7 +136,7 @@ Java:: [source,java,indent=0,subs="verbatim,quotes"] ---- Mono completion = client.sql("CREATE TABLE person (id VARCHAR(255) PRIMARY KEY, name VARCHAR(255), age INTEGER);") - .then(); + .then(); ---- Kotlin:: @@ -144,7 +144,7 @@ Kotlin:: [source,kotlin,indent=0,subs="verbatim,quotes"] ---- client.sql("CREATE TABLE person (id VARCHAR(255) PRIMARY KEY, name VARCHAR(255), age INTEGER);") - .await() + .await() ---- ====== @@ -173,7 +173,7 @@ Java:: [source,java,indent=0,subs="verbatim,quotes"] ---- Mono> first = client.sql("SELECT id, name FROM person") - .fetch().first(); + .fetch().first(); ---- Kotlin:: @@ -181,7 +181,7 @@ Kotlin:: [source,kotlin,indent=0,subs="verbatim,quotes"] ---- val first = client.sql("SELECT id, name FROM person") - .fetch().awaitSingle() + .fetch().awaitSingle() ---- ====== @@ -194,8 +194,8 @@ Java:: [source,java,indent=0,subs="verbatim,quotes"] ---- Mono> first = client.sql("SELECT id, name FROM person WHERE first_name = :fn") - .bind("fn", "Joe") - .fetch().first(); + .bind("fn", "Joe") + .fetch().first(); ---- Kotlin:: @@ -203,8 +203,8 @@ Kotlin:: [source,kotlin,indent=0,subs="verbatim,quotes"] ---- val first = client.sql("SELECT id, name FROM person WHERE first_name = :fn") - .bind("fn", "Joe") - .fetch().awaitSingle() + .bind("fn", "Joe") + .fetch().awaitSingle() ---- ====== @@ -240,8 +240,8 @@ Java:: [source,java,indent=0,subs="verbatim,quotes"] ---- Flux names = client.sql("SELECT name FROM person") - .map(row -> row.get("name", String.class)) - .all(); + .map(row -> row.get("name", String.class)) + .all(); ---- Kotlin:: @@ -249,8 +249,8 @@ Kotlin:: [source,kotlin,indent=0,subs="verbatim,quotes"] ---- val names = client.sql("SELECT name FROM person") - .map{ row: Row -> row.get("name", String.class) } - .flow() + .map{ row: Row -> row.get("name", String.class) } + .flow() ---- ====== @@ -301,8 +301,8 @@ Java:: [source,java,indent=0,subs="verbatim,quotes"] ---- Mono affectedRows = client.sql("UPDATE person SET first_name = :fn") - .bind("fn", "Joe") - .fetch().rowsUpdated(); + .bind("fn", "Joe") + .fetch().rowsUpdated(); ---- Kotlin:: @@ -310,8 +310,8 @@ Kotlin:: [source,kotlin,indent=0,subs="verbatim,quotes"] ---- val affectedRows = client.sql("UPDATE person SET first_name = :fn") - .bind("fn", "Joe") - .fetch().awaitRowsUpdated() + .bind("fn", "Joe") + .fetch().awaitRowsUpdated() ---- ====== @@ -337,9 +337,9 @@ The following example shows parameter binding for a query: [source,java] ---- - db.sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)") - .bind("id", "joe") - .bind("name", "Joe") + db.sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)") + .bind("id", "joe") + .bind("name", "Joe") .bind("age", 34); ---- @@ -369,9 +369,9 @@ Indices are zero based. [source,java] ---- - db.sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)") - .bind(0, "joe") - .bind(1, "Joe") + db.sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)") + .bind(0, "joe") + .bind(1, "Joe") .bind(2, 34); ---- @@ -379,9 +379,9 @@ In case your application is binding to many parameters, the same can be achieved [source,java] ---- - List values = List.of("joe", "Joe", 34); - db.sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)") - .bindValues(values); + List values = List.of("joe", "Joe", 34); + db.sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)") + .bindValues(values); ---- @@ -428,7 +428,7 @@ Java:: tuples.add(new Object[] {"Ann", 50}); client.sql("SELECT id, name, state FROM table WHERE (name, age) IN (:tuples)") - .bind("tuples", tuples); + .bind("tuples", tuples); ---- Kotlin:: @@ -440,7 +440,7 @@ Kotlin:: tuples.add(arrayOf("Ann", 50)) client.sql("SELECT id, name, state FROM table WHERE (name, age) IN (:tuples)") - .bind("tuples", tuples) + .bind("tuples", tuples) ---- ====== @@ -455,7 +455,7 @@ Java:: [source,java,indent=0,subs="verbatim,quotes"] ---- client.sql("SELECT id, name, state FROM table WHERE age IN (:ages)") - .bind("ages", Arrays.asList(35, 50)); + .bind("ages", Arrays.asList(35, 50)); ---- Kotlin:: @@ -463,7 +463,7 @@ Kotlin:: [source,kotlin,indent=0,subs="verbatim,quotes"] ---- client.sql("SELECT id, name, state FROM table WHERE age IN (:ages)") - .bind("ages", arrayOf(35, 50)) + .bind("ages", arrayOf(35, 50)) ---- ====== @@ -490,9 +490,9 @@ Java:: [source,java,indent=0,subs="verbatim,quotes"] ---- client.sql("INSERT INTO table (name, state) VALUES(:name, :state)") - .filter((s, next) -> next.execute(s.returnGeneratedValues("id"))) - .bind("name", …) - .bind("state", …); + .filter((s, next) -> next.execute(s.returnGeneratedValues("id"))) + .bind("name", …) + .bind("state", …); ---- Kotlin:: @@ -516,10 +516,10 @@ Java:: [source,java,indent=0,subs="verbatim,quotes"] ---- client.sql("INSERT INTO table (name, state) VALUES(:name, :state)") - .filter(statement -> s.returnGeneratedValues("id")); + .filter(statement -> s.returnGeneratedValues("id")); client.sql("SELECT id, name, state FROM table") - .filter(statement -> s.fetchSize(25)); + .filter(statement -> s.fetchSize(25)); ---- Kotlin:: @@ -527,10 +527,10 @@ Kotlin:: [source,kotlin,indent=0,subs="verbatim,quotes"] ---- client.sql("INSERT INTO table (name, state) VALUES(:name, :state)") - .filter { statement -> s.returnGeneratedValues("id") } + .filter { statement -> s.returnGeneratedValues("id") } client.sql("SELECT id, name, state FROM table") - .filter { statement -> s.fetchSize(25) } + .filter { statement -> s.fetchSize(25) } ---- ====== diff --git a/framework-docs/modules/ROOT/pages/integration/cds.adoc b/framework-docs/modules/ROOT/pages/integration/cds.adoc index aeffe326c1..c660a4c650 100644 --- a/framework-docs/modules/ROOT/pages/integration/cds.adoc +++ b/framework-docs/modules/ROOT/pages/integration/cds.adoc @@ -55,11 +55,11 @@ a "shared objects file" source, as shown in the following example: [source,shell,indent=0,subs="verbatim"] ---- - [0.064s][info][class,load] org.springframework.core.env.EnvironmentCapable source: shared objects file (top) - [0.064s][info][class,load] org.springframework.beans.factory.BeanFactory source: shared objects file (top) - [0.064s][info][class,load] org.springframework.beans.factory.ListableBeanFactory source: shared objects file (top) - [0.064s][info][class,load] org.springframework.beans.factory.HierarchicalBeanFactory source: shared objects file (top) - [0.065s][info][class,load] org.springframework.context.MessageSource source: shared objects file (top) + [0.064s][info][class,load] org.springframework.core.env.EnvironmentCapable source: shared objects file (top) + [0.064s][info][class,load] org.springframework.beans.factory.BeanFactory source: shared objects file (top) + [0.064s][info][class,load] org.springframework.beans.factory.ListableBeanFactory source: shared objects file (top) + [0.064s][info][class,load] org.springframework.beans.factory.HierarchicalBeanFactory source: shared objects file (top) + [0.065s][info][class,load] org.springframework.context.MessageSource source: shared objects file (top) ---- If CDS can't be enabled or if you have a large number of classes that are not loaded from the cache, make sure that diff --git a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc index d6a143eab1..0f23a35d0e 100644 --- a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc +++ b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc @@ -30,36 +30,36 @@ Java:: + [source,java,indent=0,subs="verbatim"] ---- -RestClient defaultClient = RestClient.create(); - -RestClient customClient = RestClient.builder() - .requestFactory(new HttpComponentsClientHttpRequestFactory()) - .messageConverters(converters -> converters.add(new MyCustomMessageConverter())) - .baseUrl("https://example.com") - .defaultUriVariables(Map.of("variable", "foo")) - .defaultHeader("My-Header", "Foo") - .defaultCookie("My-Cookie", "Bar") - .requestInterceptor(myCustomInterceptor) - .requestInitializer(myCustomInitializer) - .build(); + RestClient defaultClient = RestClient.create(); + + RestClient customClient = RestClient.builder() + .requestFactory(new HttpComponentsClientHttpRequestFactory()) + .messageConverters(converters -> converters.add(new MyCustomMessageConverter())) + .baseUrl("https://example.com") + .defaultUriVariables(Map.of("variable", "foo")) + .defaultHeader("My-Header", "Foo") + .defaultCookie("My-Cookie", "Bar") + .requestInterceptor(myCustomInterceptor) + .requestInitializer(myCustomInitializer) + .build(); ---- Kotlin:: + [source,kotlin,indent=0,subs="verbatim"] ---- -val defaultClient = RestClient.create() - -val customClient = RestClient.builder() - .requestFactory(HttpComponentsClientHttpRequestFactory()) - .messageConverters { converters -> converters.add(MyCustomMessageConverter()) } - .baseUrl("https://example.com") - .defaultUriVariables(mapOf("variable" to "foo")) - .defaultHeader("My-Header", "Foo") - .defaultCookie("My-Cookie", "Bar") - .requestInterceptor(myCustomInterceptor) - .requestInitializer(myCustomInitializer) - .build() + val defaultClient = RestClient.create() + + val customClient = RestClient.builder() + .requestFactory(HttpComponentsClientHttpRequestFactory()) + .messageConverters { converters -> converters.add(MyCustomMessageConverter()) } + .baseUrl("https://example.com") + .defaultUriVariables(mapOf("variable" to "foo")) + .defaultHeader("My-Header", "Foo") + .defaultCookie("My-Cookie", "Bar") + .requestInterceptor(myCustomInterceptor) + .requestInitializer(myCustomInitializer) + .build() ---- ====== @@ -81,20 +81,20 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- -int id = 42; -restClient.get() - .uri("https://example.com/orders/{id}", id) - .... + int id = 42; + restClient.get() + .uri("https://example.com/orders/{id}", id) + // ... ---- Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- -val id = 42 -restClient.get() - .uri("https://example.com/orders/{id}", id) - ... + val id = 42 + restClient.get() + .uri("https://example.com/orders/{id}", id) + // ... ---- ====== @@ -133,12 +133,12 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- -String result = restClient.get() <1> - .uri("https://example.com") <2> - .retrieve() <3> - .body(String.class); <4> - -System.out.println(result); <5> + String result = restClient.get() <1> + .uri("https://example.com") <2> + .retrieve() <3> + .body(String.class); <4> + + System.out.println(result); <5> ---- <1> Set up a GET request <2> Specify the URL to connect to @@ -150,12 +150,12 @@ Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- -val result= restClient.get() <1> - .uri("https://example.com") <2> - .retrieve() <3> - .body() <4> - -println(result) <5> + val result= restClient.get() <1> + .uri("https://example.com") <2> + .retrieve() <3> + .body() <4> + + println(result) <5> ---- <1> Set up a GET request <2> Specify the URL to connect to @@ -172,14 +172,14 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- -ResponseEntity result = restClient.get() <1> - .uri("https://example.com") <1> - .retrieve() - .toEntity(String.class); <2> - -System.out.println("Response status: " + result.getStatusCode()); <3> -System.out.println("Response headers: " + result.getHeaders()); <3> -System.out.println("Contents: " + result.getBody()); <3> + ResponseEntity result = restClient.get() <1> + .uri("https://example.com") <1> + .retrieve() + .toEntity(String.class); <2> + + System.out.println("Response status: " + result.getStatusCode()); <3> + System.out.println("Response headers: " + result.getHeaders()); <3> + System.out.println("Contents: " + result.getBody()); <3> ---- <1> Set up a GET request for the specified URL <2> Convert the response into a `ResponseEntity` @@ -189,14 +189,14 @@ Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- -val result = restClient.get() <1> - .uri("https://example.com") <1> - .retrieve() - .toEntity() <2> - -println("Response status: " + result.statusCode) <3> -println("Response headers: " + result.headers) <3> -println("Contents: " + result.body) <3> + val result = restClient.get() <1> + .uri("https://example.com") <1> + .retrieve() + .toEntity() <2> + + println("Response status: " + result.statusCode) <3> + println("Response headers: " + result.headers) <3> + println("Contents: " + result.body) <3> ---- <1> Set up a GET request for the specified URL <2> Convert the response into a `ResponseEntity` @@ -212,12 +212,12 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- -int id = ...; -Pet pet = restClient.get() - .uri("https://petclinic.example.com/pets/{id}", id) <1> - .accept(APPLICATION_JSON) <2> - .retrieve() - .body(Pet.class); <3> + int id = ...; + Pet pet = restClient.get() + .uri("https://petclinic.example.com/pets/{id}", id) <1> + .accept(APPLICATION_JSON) <2> + .retrieve() + .body(Pet.class); <3> ---- <1> Using URI variables <2> Set the `Accept` header to `application/json` @@ -227,12 +227,12 @@ Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- -val id = ... -val pet = restClient.get() - .uri("https://petclinic.example.com/pets/{id}", id) <1> - .accept(APPLICATION_JSON) <2> - .retrieve() - .body() <3> + val id = ... + val pet = restClient.get() + .uri("https://petclinic.example.com/pets/{id}", id) <1> + .accept(APPLICATION_JSON) <2> + .retrieve() + .body() <3> ---- <1> Using URI variables <2> Set the `Accept` header to `application/json` @@ -247,13 +247,13 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- -Pet pet = ... <1> -ResponseEntity response = restClient.post() <2> - .uri("https://petclinic.example.com/pets/new") <2> - .contentType(APPLICATION_JSON) <3> - .body(pet) <4> - .retrieve() - .toBodilessEntity(); <5> + Pet pet = ... <1> + ResponseEntity response = restClient.post() <2> + .uri("https://petclinic.example.com/pets/new") <2> + .contentType(APPLICATION_JSON) <3> + .body(pet) <4> + .retrieve() + .toBodilessEntity(); <5> ---- <1> Create a `Pet` domain object <2> Set up a POST request, and the URL to connect to @@ -265,13 +265,13 @@ Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- -val pet: Pet = ... <1> -val response = restClient.post() <2> - .uri("https://petclinic.example.com/pets/new") <2> - .contentType(APPLICATION_JSON) <3> - .body(pet) <4> - .retrieve() - .toBodilessEntity() <5> + val pet: Pet = ... <1> + val response = restClient.post() <2> + .uri("https://petclinic.example.com/pets/new") <2> + .contentType(APPLICATION_JSON) <3> + .body(pet) <4> + .retrieve() + .toBodilessEntity() <5> ---- <1> Create a `Pet` domain object <2> Set up a POST request, and the URL to connect to @@ -291,13 +291,13 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- -String result = restClient.get() <1> - .uri("https://example.com/this-url-does-not-exist") <1> - .retrieve() - .onStatus(HttpStatusCode::is4xxClientError, (request, response) -> { <2> - throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()); <3> - }) - .body(String.class); + String result = restClient.get() <1> + .uri("https://example.com/this-url-does-not-exist") <1> + .retrieve() + .onStatus(HttpStatusCode::is4xxClientError, (request, response) -> { <2> + throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()); <3> + }) + .body(String.class); ---- <1> Create a GET request for a URL that returns a 404 status code <2> Set up a status handler for all 4xx status codes @@ -307,12 +307,12 @@ Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- -val result = restClient.get() <1> - .uri("https://example.com/this-url-does-not-exist") <1> - .retrieve() - .onStatus(HttpStatusCode::is4xxClientError) { _, response -> <2> - throw MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()) } <3> - .body() + val result = restClient.get() <1> + .uri("https://example.com/this-url-does-not-exist") <1> + .retrieve() + .onStatus(HttpStatusCode::is4xxClientError) { _, response -> <2> + throw MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()) } <3> + .body() ---- <1> Create a GET request for a URL that returns a 404 status code <2> Set up a status handler for all 4xx status codes @@ -330,18 +330,18 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- -Pet result = restClient.get() - .uri("https://petclinic.example.com/pets/{id}", id) - .accept(APPLICATION_JSON) - .exchange((request, response) -> { <1> - if (response.getStatusCode().is4xxClientError()) { <2> - throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()); <2> - } - else { - Pet pet = convertResponse(response); <3> - return pet; - } - }); + Pet result = restClient.get() + .uri("https://petclinic.example.com/pets/{id}", id) + .accept(APPLICATION_JSON) + .exchange((request, response) -> { <1> + if (response.getStatusCode().is4xxClientError()) { <2> + throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()); <2> + } + else { + Pet pet = convertResponse(response); <3> + return pet; + } + }); ---- <1> `exchange` provides the request and response <2> Throw an exception when the response has a 4xx status code @@ -351,17 +351,17 @@ Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- -val result = restClient.get() - .uri("https://petclinic.example.com/pets/{id}", id) - .accept(MediaType.APPLICATION_JSON) - .exchange { request, response -> <1> - if (response.getStatusCode().is4xxClientError()) { <2> - throw MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()) <2> - } else { - val pet: Pet = convertResponse(response) <3> - pet - } - } + val result = restClient.get() + .uri("https://petclinic.example.com/pets/{id}", id) + .accept(MediaType.APPLICATION_JSON) + .exchange { request, response -> <1> + if (response.getStatusCode().is4xxClientError()) { <2> + throw MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()) <2> + } else { + val pet: Pet = convertResponse(response) <3> + pet + } + } ---- <1> `exchange` provides the request and response <2> Throw an exception when the response has a 4xx status code @@ -380,15 +380,14 @@ To serialize only a subset of the object properties, you can specify a {baeldung [source,java,indent=0,subs="verbatim"] ---- -MappingJacksonValue value = new MappingJacksonValue(new User("eric", "7!jd#h23")); -value.setSerializationView(User.WithoutPasswordView.class); - -ResponseEntity response = restClient.post() // or RestTemplate.postForEntity - .contentType(APPLICATION_JSON) - .body(value) - .retrieve() - .toBodilessEntity(); - + MappingJacksonValue value = new MappingJacksonValue(new User("eric", "7!jd#h23")); + value.setSerializationView(User.WithoutPasswordView.class); + + ResponseEntity response = restClient.post() // or RestTemplate.postForEntity + .contentType(APPLICATION_JSON) + .body(value) + .retrieve() + .toBodilessEntity(); ---- ==== Multipart @@ -398,24 +397,24 @@ For example: [source,java,indent=0,subs="verbatim"] ---- -MultiValueMap parts = new LinkedMultiValueMap<>(); - -parts.add("fieldPart", "fieldValue"); -parts.add("filePart", new FileSystemResource("...logo.png")); -parts.add("jsonPart", new Person("Jason")); - -HttpHeaders headers = new HttpHeaders(); -headers.setContentType(MediaType.APPLICATION_XML); -parts.add("xmlPart", new HttpEntity<>(myBean, headers)); - -// send using RestClient.post or RestTemplate.postForEntity + MultiValueMap parts = new LinkedMultiValueMap<>(); + + parts.add("fieldPart", "fieldValue"); + parts.add("filePart", new FileSystemResource("...logo.png")); + parts.add("jsonPart", new Person("Jason")); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_XML); + parts.add("xmlPart", new HttpEntity<>(myBean, headers)); + + // send using RestClient.post or RestTemplate.postForEntity ---- In most cases, you do not have to specify the `Content-Type` for each part. The content type is determined automatically based on the `HttpMessageConverter` chosen to serialize it or, in the case of a `Resource`, based on the file extension. If necessary, you can explicitly provide the `MediaType` with an `HttpEntity` wrapper. -Once the `MultiValueMap` is ready, you can use it as the body of a `POST` request, using `RestClient.post().body(parts)` (or `RestTemplate.postForObject`). +Once the `MultiValueMap` is ready, you can use it as the body of a `POST` request, using `RestClient.post().body(parts)` (or `RestTemplate.postForObject`). If the `MultiValueMap` contains at least one non-`String` value, the `Content-Type` is set to `multipart/form-data` by the `FormHttpMessageConverter`. If the `MultiValueMap` has `String` values, the `Content-Type` defaults to `application/x-www-form-urlencoded`. @@ -1137,11 +1136,11 @@ performed through the client: [source,java,indent=0,subs="verbatim,quotes"] ---- - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(myErrorHandler); - - RestTemplateAdapter adapter = RestTemplateAdapter.create(restTemplate); - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build(); + RestTemplate restTemplate = new RestTemplate(); + restTemplate.setErrorHandler(myErrorHandler); + + RestTemplateAdapter adapter = RestTemplateAdapter.create(restTemplate); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build(); ---- For more details and options, see the Javadoc of `setErrorHandler` in `RestTemplate` and diff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc index 9e09a69411..6893fb5a48 100644 --- a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc +++ b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc @@ -215,45 +215,43 @@ For suspending functions, a `TransactionalOperator.executeAndAwait` extension is [source,kotlin,indent=0] ---- - import org.springframework.transaction.reactive.executeAndAwait + import org.springframework.transaction.reactive.executeAndAwait - class PersonRepository(private val operator: TransactionalOperator) { + class PersonRepository(private val operator: TransactionalOperator) { - suspend fun initDatabase() = operator.executeAndAwait { - insertPerson1() - insertPerson2() - } + suspend fun initDatabase() = operator.executeAndAwait { + insertPerson1() + insertPerson2() + } - private suspend fun insertPerson1() { - // INSERT SQL statement - } + private suspend fun insertPerson1() { + // INSERT SQL statement + } - private suspend fun insertPerson2() { - // INSERT SQL statement - } - } + private suspend fun insertPerson2() { + // INSERT SQL statement + } + } ---- For Kotlin `Flow`, a `Flow.transactional` extension is provided. [source,kotlin,indent=0] ---- - import org.springframework.transaction.reactive.transactional + import org.springframework.transaction.reactive.transactional - class PersonRepository(private val operator: TransactionalOperator) { + class PersonRepository(private val operator: TransactionalOperator) { - fun updatePeople() = findPeople().map(::updatePerson).transactional(operator) + fun updatePeople() = findPeople().map(::updatePerson).transactional(operator) - private fun findPeople(): Flow { - // SELECT SQL statement - } + private fun findPeople(): Flow { + // SELECT SQL statement + } - private suspend fun updatePerson(person: Person): Person { - // UPDATE SQL statement - } - } + private suspend fun updatePerson(person: Person): Person { + // UPDATE SQL statement + } + } ---- - - diff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc index 64da5a0b63..3fa561bf51 100644 --- a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc +++ b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc @@ -296,17 +296,17 @@ for example when writing a `org.springframework.core.convert.converter.Converter [source,kotlin,indent=0] ---- -class ListOfFooConverter : Converter, CustomJavaList> { - // ... -} + class ListOfFooConverter : Converter, CustomJavaList> { + // ... + } ---- When converting any kind of objects, star projection with `*` can be used instead of `out Any`. [source,kotlin,indent=0] ---- -class ListOfAnyConverter : Converter, CustomJavaList<*>> { - // ... -} + class ListOfAnyConverter : Converter, CustomJavaList<*>> { + // ... + } ---- NOTE: Spring Framework does not leverage yet declaration-site variance type information for injecting beans, @@ -340,13 +340,14 @@ file with a `spring.test.constructor.autowire.mode = all` property. [source,kotlin,indent=0] ---- -@SpringJUnitConfig(TestConfig::class) -@TestConstructor(autowireMode = AutowireMode.ALL) -class OrderServiceIntegrationTests(val orderService: OrderService, - val customerService: CustomerService) { - - // tests that use the injected OrderService and CustomerService -} + @SpringJUnitConfig(TestConfig::class) + @TestConstructor(autowireMode = AutowireMode.ALL) + class OrderServiceIntegrationTests( + val orderService: OrderService, + val customerService: CustomerService) { + + // tests that use the injected OrderService and CustomerService + } ---- @@ -368,29 +369,29 @@ The following example demonstrates `@BeforeAll` and `@AfterAll` annotations on n @TestInstance(TestInstance.Lifecycle.PER_CLASS) class IntegrationTests { - val application = Application(8181) - val client = WebClient.create("http://localhost:8181") + val application = Application(8181) + val client = WebClient.create("http://localhost:8181") - @BeforeAll - fun beforeAll() { - application.start() - } + @BeforeAll + fun beforeAll() { + application.start() + } - @Test - fun `Find all users on HTML page`() { - client.get().uri("/users") - .accept(TEXT_HTML) - .retrieve() - .bodyToMono() - .test() - .expectNextMatches { it.contains("Foo") } - .verifyComplete() - } + @Test + fun `Find all users on HTML page`() { + client.get().uri("/users") + .accept(TEXT_HTML) + .retrieve() + .bodyToMono() + .test() + .expectNextMatches { it.contains("Foo") } + .verifyComplete() + } - @AfterAll - fun afterAll() { - application.stop() - } + @AfterAll + fun afterAll() { + application.stop() + } } ---- @@ -403,26 +404,27 @@ The following example shows how to do so: [source,kotlin,indent=0] ---- -class SpecificationLikeTests { + class SpecificationLikeTests { + + @Nested + @DisplayName("a calculator") + inner class Calculator { - @Nested - @DisplayName("a calculator") - inner class Calculator { - val calculator = SampleCalculator() - - @Test - fun `should return the result of adding the first number to the second number`() { - val sum = calculator.sum(2, 4) - assertEquals(6, sum) - } - - @Test - fun `should return the result of subtracting the second number from the first number`() { - val subtract = calculator.subtract(4, 2) - assertEquals(2, subtract) - } - } -} + val calculator = SampleCalculator() + + @Test + fun `should return the result of adding the first number to the second number`() { + val sum = calculator.sum(2, 4) + assertEquals(6, sum) + } + + @Test + fun `should return the result of subtracting the second number from the first number`() { + val subtract = calculator.subtract(4, 2) + assertEquals(2, subtract) + } + } + } ---- diff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc index e594069b0d..0bac57fe19 100644 --- a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc +++ b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc @@ -1,8 +1,6 @@ [[kotlin-web]] = Web - - [[router-dsl]] == Router DSL @@ -16,27 +14,27 @@ These DSL let you write clean and idiomatic Kotlin code to build a `RouterFuncti [source,kotlin,indent=0] ---- -@Configuration -class RouterRouterConfiguration { - - @Bean - fun mainRouter(userHandler: UserHandler) = router { - accept(TEXT_HTML).nest { - GET("/") { ok().render("index") } - GET("/sse") { ok().render("sse") } - GET("/users", userHandler::findAllView) - } - "/api".nest { - accept(APPLICATION_JSON).nest { - GET("/users", userHandler::findAll) + @Configuration + class RouterRouterConfiguration { + + @Bean + fun mainRouter(userHandler: UserHandler) = router { + accept(TEXT_HTML).nest { + GET("/") { ok().render("index") } + GET("/sse") { ok().render("sse") } + GET("/users", userHandler::findAllView) } - accept(TEXT_EVENT_STREAM).nest { - GET("/users", userHandler::stream) + "/api".nest { + accept(APPLICATION_JSON).nest { + GET("/users", userHandler::findAll) + } + accept(TEXT_EVENT_STREAM).nest { + GET("/users", userHandler::stream) + } } + resources("/**", ClassPathResource("static/")) } - resources("/**", ClassPathResource("static/")) } -} ---- NOTE: This DSL is programmatic, meaning that it allows custom registration logic of beans @@ -55,22 +53,22 @@ idiomatic Kotlin API and to allow better discoverability (no usage of static met [source,kotlin,indent=0] ---- -val mockMvc: MockMvc = ... -mockMvc.get("/person/{name}", "Lee") { - secure = true - accept = APPLICATION_JSON - headers { - contentLanguage = Locale.FRANCE + val mockMvc: MockMvc = ... + mockMvc.get("/person/{name}", "Lee") { + secure = true + accept = APPLICATION_JSON + headers { + contentLanguage = Locale.FRANCE + } + principal = Principal { "foo" } + }.andExpect { + status { isOk } + content { contentType(APPLICATION_JSON) } + jsonPath("$.name") { value("Lee") } + content { json("""{"someBoolean": false}""", false) } + }.andDo { + print() } - principal = Principal { "foo" } -}.andExpect { - status { isOk } - content { contentType(APPLICATION_JSON) } - jsonPath("$.name") { value("Lee") } - content { json("""{"someBoolean": false}""", false) } -}.andDo { - print() -} ---- @@ -89,9 +87,9 @@ is possible to use such feature to render Kotlin-based templates with `build.gradle.kts` [source,kotlin,indent=0] ---- -dependencies { - runtime("org.jetbrains.kotlin:kotlin-scripting-jsr223:${kotlinVersion}") -} + dependencies { + runtime("org.jetbrains.kotlin:kotlin-scripting-jsr223:${kotlinVersion}") + } ---- Configuration is usually done with `ScriptTemplateConfigurer` and `ScriptTemplateViewResolver` beans. @@ -99,23 +97,23 @@ Configuration is usually done with `ScriptTemplateConfigurer` and `ScriptTemplat `KotlinScriptConfiguration.kt` [source,kotlin,indent=0] ---- -@Configuration -class KotlinScriptConfiguration { - - @Bean - fun kotlinScriptConfigurer() = ScriptTemplateConfigurer().apply { - engineName = "kotlin" - setScripts("scripts/render.kts") - renderFunction = "render" - isSharedEngine = false + @Configuration + class KotlinScriptConfiguration { + + @Bean + fun kotlinScriptConfigurer() = ScriptTemplateConfigurer().apply { + engineName = "kotlin" + setScripts("scripts/render.kts") + renderFunction = "render" + isSharedEngine = false + } + + @Bean + fun kotlinScriptViewResolver() = ScriptTemplateViewResolver().apply { + setPrefix("templates/") + setSuffix(".kts") + } } - - @Bean - fun kotlinScriptViewResolver() = ScriptTemplateViewResolver().apply { - setPrefix("templates/") - setSuffix(".kts") - } -} ---- See the https://github.com/sdeleuze/kotlin-script-templating[kotlin-script-templating] example @@ -127,7 +125,7 @@ project for more details. == Kotlin multiplatform serialization {kotlin-github-org}/kotlinx.serialization[Kotlin multiplatform serialization] is -supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently targets CBOR, JSON, and ProtoBuf formats. +supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The built-in support currently targets CBOR, JSON, and ProtoBuf formats. To enable it, follow {kotlin-github-org}/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin. With Spring MVC and WebFlux, both Kotlin serialization and Jackson will be configured by default if they are in the classpath since @@ -135,6 +133,3 @@ Kotlin serialization is designed to serialize only Kotlin classes annotated with With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration, if Jackson is needed configure `KotlinSerializationJsonMessageConverter` manually. - - - diff --git a/framework-docs/modules/ROOT/pages/testing/mockmvc/hamcrest/async-requests.adoc b/framework-docs/modules/ROOT/pages/testing/mockmvc/hamcrest/async-requests.adoc index 949b9ab8a9..f6f5d9f14f 100644 --- a/framework-docs/modules/ROOT/pages/testing/mockmvc/hamcrest/async-requests.adoc +++ b/framework-docs/modules/ROOT/pages/testing/mockmvc/hamcrest/async-requests.adoc @@ -26,16 +26,16 @@ Java:: @Test void test() throws Exception { - MvcResult mvcResult = this.mockMvc.perform(get("/path")) - .andExpect(status().isOk()) <1> - .andExpect(request().asyncStarted()) <2> - .andExpect(request().asyncResult("body")) <3> - .andReturn(); + MvcResult mvcResult = this.mockMvc.perform(get("/path")) + .andExpect(status().isOk()) <1> + .andExpect(request().asyncStarted()) <2> + .andExpect(request().asyncResult("body")) <3> + .andReturn(); - this.mockMvc.perform(asyncDispatch(mvcResult)) <4> - .andExpect(status().isOk()) <5> - .andExpect(content().string("body")); - } + this.mockMvc.perform(asyncDispatch(mvcResult)) <4> + .andExpect(status().isOk()) <5> + .andExpect(content().string("body")); + } ---- <1> Check response status is still unchanged <2> Async processing must have started diff --git a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc index 2642be67ed..b155859ee5 100644 --- a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc +++ b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc @@ -396,7 +396,7 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- - import org.springframework.test.web.reactive.server.expectBody + import org.springframework.test.web.reactive.server.expectBody client.get().uri("/persons/1") .exchange() diff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-body.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-body.adoc index bd52881b45..7ff92ff268 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-body.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-body.adoc @@ -306,34 +306,34 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- -Resource resource = ... -Mono result = webClient - .post() - .uri("https://example.com") - .body(Flux.concat( - FormPartEvent.create("field", "field value"), - FilePartEvent.create("file", resource) - ), PartEvent.class) - .retrieve() - .bodyToMono(String.class); + Resource resource = ... + Mono result = webClient + .post() + .uri("https://example.com") + .body(Flux.concat( + FormPartEvent.create("field", "field value"), + FilePartEvent.create("file", resource) + ), PartEvent.class) + .retrieve() + .bodyToMono(String.class); ---- Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- -var resource: Resource = ... -var result: Mono = webClient - .post() - .uri("https://example.com") - .body( - Flux.concat( - FormPartEvent.create("field", "field value"), - FilePartEvent.create("file", resource) + var resource: Resource = ... + var result: Mono = webClient + .post() + .uri("https://example.com") + .body( + Flux.concat( + FormPartEvent.create("field", "field value"), + FilePartEvent.create("file", resource) + ) ) - ) - .retrieve() - .bodyToMono() + .retrieve() + .bodyToMono() ---- ====== diff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-builder.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-builder.adoc index 53a2fc247c..d8ed1f3885 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-builder.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-builder.adoc @@ -390,29 +390,29 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- - HttpClient httpClient = HttpClient.newBuilder() - .followRedirects(Redirect.NORMAL) - .connectTimeout(Duration.ofSeconds(20)) - .build(); + HttpClient httpClient = HttpClient.newBuilder() + .followRedirects(Redirect.NORMAL) + .connectTimeout(Duration.ofSeconds(20)) + .build(); - ClientHttpConnector connector = - new JdkClientHttpConnector(httpClient, new DefaultDataBufferFactory()); + ClientHttpConnector connector = + new JdkClientHttpConnector(httpClient, new DefaultDataBufferFactory()); - WebClient webClient = WebClient.builder().clientConnector(connector).build(); + WebClient webClient = WebClient.builder().clientConnector(connector).build(); ---- Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- - val httpClient = HttpClient.newBuilder() - .followRedirects(Redirect.NORMAL) - .connectTimeout(Duration.ofSeconds(20)) - .build() + val httpClient = HttpClient.newBuilder() + .followRedirects(Redirect.NORMAL) + .connectTimeout(Duration.ofSeconds(20)) + .build() - val connector = JdkClientHttpConnector(httpClient, DefaultDataBufferFactory()) + val connector = JdkClientHttpConnector(httpClient, DefaultDataBufferFactory()) - val webClient = WebClient.builder().clientConnector(connector).build() + val webClient = WebClient.builder().clientConnector(connector).build() ---- ====== diff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-filter.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-filter.adoc index d63ed06a9f..a2d4ad961f 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-filter.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-filter.adoc @@ -158,65 +158,65 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- -public class MultipartExchangeFilterFunction implements ExchangeFilterFunction { - - @Override - public Mono filter(ClientRequest request, ExchangeFunction next) { - if (MediaType.MULTIPART_FORM_DATA.includes(request.headers().getContentType()) - && (request.method() == HttpMethod.PUT || request.method() == HttpMethod.POST)) { - return next.exchange(ClientRequest.from(request).body((outputMessage, context) -> - request.body().insert(new BufferingDecorator(outputMessage), context)).build() - ); - } else { - return next.exchange(request); - } - } - - private static final class BufferingDecorator extends ClientHttpRequestDecorator { - - private BufferingDecorator(ClientHttpRequest delegate) { - super(delegate); - } - - @Override - public Mono writeWith(Publisher body) { - return DataBufferUtils.join(body).flatMap(buffer -> { - getHeaders().setContentLength(buffer.readableByteCount()); - return super.writeWith(Mono.just(buffer)); - }); - } - } -} + public class MultipartExchangeFilterFunction implements ExchangeFilterFunction { + + @Override + public Mono filter(ClientRequest request, ExchangeFunction next) { + if (MediaType.MULTIPART_FORM_DATA.includes(request.headers().getContentType()) + && (request.method() == HttpMethod.PUT || request.method() == HttpMethod.POST)) { + return next.exchange(ClientRequest.from(request).body((outputMessage, context) -> + request.body().insert(new BufferingDecorator(outputMessage), context)).build() + ); + } else { + return next.exchange(request); + } + } + + private static final class BufferingDecorator extends ClientHttpRequestDecorator { + + private BufferingDecorator(ClientHttpRequest delegate) { + super(delegate); + } + + @Override + public Mono writeWith(Publisher body) { + return DataBufferUtils.join(body).flatMap(buffer -> { + getHeaders().setContentLength(buffer.readableByteCount()); + return super.writeWith(Mono.just(buffer)); + }); + } + } + } ---- Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- -class MultipartExchangeFilterFunction : ExchangeFilterFunction { - - override fun filter(request: ClientRequest, next: ExchangeFunction): Mono { - return if (MediaType.MULTIPART_FORM_DATA.includes(request.headers().getContentType()) - && (request.method() == HttpMethod.PUT || request.method() == HttpMethod.POST)) { - next.exchange(ClientRequest.from(request) - .body { message, context -> request.body().insert(BufferingDecorator(message), context) } - .build()) - } - else { - next.exchange(request) - } - - } - - private class BufferingDecorator(delegate: ClientHttpRequest) : ClientHttpRequestDecorator(delegate) { - override fun writeWith(body: Publisher): Mono { - return DataBufferUtils.join(body) - .flatMap { - headers.contentLength = it.readableByteCount().toLong() - super.writeWith(Mono.just(it)) - } - } - } -} + class MultipartExchangeFilterFunction : ExchangeFilterFunction { + + override fun filter(request: ClientRequest, next: ExchangeFunction): Mono { + return if (MediaType.MULTIPART_FORM_DATA.includes(request.headers().getContentType()) + && (request.method() == HttpMethod.PUT || request.method() == HttpMethod.POST)) { + next.exchange(ClientRequest.from(request) + .body { message, context -> request.body().insert(BufferingDecorator(message), context) } + .build()) + } + else { + next.exchange(request) + } + + } + + private class BufferingDecorator(delegate: ClientHttpRequest) : ClientHttpRequestDecorator(delegate) { + override fun writeWith(body: Publisher): Mono { + return DataBufferUtils.join(body) + .flatMap { + headers.contentLength = it.readableByteCount().toLong() + super.writeWith(Mono.just(it)) + } + } + } + } ---- -====== \ No newline at end of file +====== diff --git a/framework-docs/modules/ROOT/pages/web/webflux-websocket.adoc b/framework-docs/modules/ROOT/pages/web/webflux-websocket.adoc index 1e7f397c19..04ea4fa386 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux-websocket.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux-websocket.adoc @@ -207,14 +207,14 @@ Kotlin:: class ExampleHandler : WebSocketHandler { override fun handle(session: WebSocketSession): Mono { - return session.receive() // <1> + return session.receive() // <1> .doOnNext { // ... // <2> } .concatMap { // ... // <3> } - .then() // <4> + .then() // <4> } } ---- @@ -268,16 +268,16 @@ Kotlin:: override fun handle(session: WebSocketSession): Mono { - val output = session.receive() // <1> + val output = session.receive() // <1> .doOnNext { // ... } .concatMap { // ... } - .map { session.textMessage("Echo $it") } // <2> + .map { session.textMessage("Echo $it") } // <2> - return session.send(output) // <3> + return session.send(output) // <3> } } ---- diff --git a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc index 15f15e7115..9d3e7fdeb7 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc @@ -149,7 +149,7 @@ Java:: DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar(); registrar.setUseIsoFormat(true); registrar.registerFormatters(registry); - } + } } ---- diff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc index 24999a0e17..632377c7b9 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc @@ -62,7 +62,7 @@ Java:: ---- class Account { - private final String firstName; + private final String firstName; public Account(@BindParam("first-name") String firstName) { this.firstName = firstName; diff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc index 7d79ea1d46..f4a6110105 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc @@ -93,8 +93,8 @@ Java:: ---- @ModelAttribute public void addAccount(@RequestParam String number) { - Mono accountMono = accountRepository.findAccount(number); - model.addAttribute("account", accountMono); + Mono accountMono = accountRepository.findAccount(number); + model.addAttribute("account", accountMono); } @PostMapping("/accounts") diff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc index e22e07b94b..553b9d9dac 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc @@ -104,21 +104,21 @@ Kotlin:: override fun requestHeader(requestHeader: RequestHeader, result: ParameterValidationResult) { // ... - } + } override fun requestParam(requestParam: RequestParam?, result: ParameterValidationResult) { // ... - } + } override fun modelAttribute(modelAttribute: ModelAttribute?, errors: ParameterErrors) { // ... - } + } // ... override fun other(result: ParameterValidationResult) { // ... - } + } }) ---- ====== diff --git a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc index 6e980e5197..9615631c6f 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc @@ -782,8 +782,8 @@ Java:: ---- WebClient webClient = WebClient.builder() .codecs(configurer -> { - CustomDecoder decoder = new CustomDecoder(); - configurer.customCodecs().registerWithDefaultConfig(decoder); + CustomDecoder decoder = new CustomDecoder(); + configurer.customCodecs().registerWithDefaultConfig(decoder); }) .build(); ---- @@ -794,8 +794,8 @@ Kotlin:: ---- val webClient = WebClient.builder() .codecs({ configurer -> - val decoder = CustomDecoder() - configurer.customCodecs().registerWithDefaultConfig(decoder) + val decoder = CustomDecoder() + configurer.customCodecs().registerWithDefaultConfig(decoder) }) .build() ---- diff --git a/framework-docs/modules/ROOT/pages/web/webmvc-functional.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-functional.adoc index 220beba7eb..ac8e5cec5b 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc-functional.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc-functional.adoc @@ -781,7 +781,7 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- - ClassPathResource index = new ClassPathResource("static/index.html"); + ClassPathResource index = new ClassPathResource("static/index.html"); List extensions = List.of("js", "css", "ico", "png", "jpg", "gif"); RequestPredicate spaPredicate = path("/api/**").or(path("/error")).or(pathExtension(extensions::contains)).negate(); RouterFunction redirectToIndex = route() @@ -793,7 +793,7 @@ Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- - val redirectToIndex = router { + val redirectToIndex = router { val index = ClassPathResource("static/index.html") val extensions = listOf("js", "css", "ico", "png", "jpg", "gif") val spaPredicate = !(path("/api/**") or path("/error") or @@ -814,16 +814,16 @@ Java:: + [source,java,indent=0,subs="verbatim,quotes"] ---- - Resource location = new FileUrlResource("public-resources/"); - RouterFunction resources = RouterFunctions.resources("/resources/**", location); + Resource location = new FileUrlResource("public-resources/"); + RouterFunction resources = RouterFunctions.resources("/resources/**", location); ---- Kotlin:: + [source,kotlin,indent=0,subs="verbatim,quotes"] ---- - val location = FileUrlResource("public-resources/") - val resources = router { resources("/resources/**", location) } + val location = FileUrlResource("public-resources/") + val resources = router { resources("/resources/**", location) } ---- ====== diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc index 7a04b5ba7f..16a055a486 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc @@ -97,7 +97,7 @@ Java:: ---- class Account { - private final String firstName; + private final String firstName; public Account(@BindParam("first-name") String firstName) { this.firstName = firstName; diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc index 34cf05e99d..99ddf8635e 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc @@ -73,12 +73,12 @@ Java:: @Override public void requestHeader(RequestHeader requestHeader, ParameterValidationResult result) { - // ... + // ... } @Override public void requestParam(@Nullable RequestParam requestParam, ParameterValidationResult result) { - // ... + // ... } @Override @@ -88,7 +88,7 @@ Java:: @Override public void other(ParameterValidationResult result) { - // ... + // ... } }); ---- @@ -103,22 +103,22 @@ Kotlin:: ex.visitResults(object : HandlerMethodValidationException.Visitor { override fun requestHeader(requestHeader: RequestHeader, result: ParameterValidationResult) { - // ... - } + // ... + } override fun requestParam(requestParam: RequestParam?, result: ParameterValidationResult) { - // ... - } + // ... + } override fun modelAttribute(modelAttribute: ModelAttribute?, errors: ParameterErrors) { - // ... - } + // ... + } // ... override fun other(result: ParameterValidationResult) { - // ... - } + // ... + } }) ---- ====== diff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc index 4301ba9708..831b1ff8df 100644 --- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc +++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc @@ -22,11 +22,11 @@ The following example code is based on it: [source,javascript,indent=0,subs="verbatim,quotes"] ---- const stompClient = new StompJs.Client({ - brokerURL: 'ws://domain.com/portfolio', - onConnect: () => { - // ... - } - }); + brokerURL: 'ws://domain.com/portfolio', + onConnect: () => { + // ... + } + }); ---- Alternatively, if you connect through SockJS, you can enable the @@ -47,5 +47,3 @@ interactive web application] -- a getting started guide. * https://github.com/rstoyanchev/spring-websocket-portfolio[Stock Portfolio] -- a sample application. - - From a22d204681c575c3f61c325d205a96fb92ea8e7a Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Mon, 14 Apr 2025 11:24:55 +0200 Subject: [PATCH 3/4] Remove duplicate words in Java source code Discovered using regular expression: \b(\w+)\s+\1\b[^(}] --- .../factory/support/MethodOverrides.java | 4 ++-- .../beans/factory/support/MethodReplacer.java | 4 ++-- .../PropertiesBeanDefinitionReader.java | 8 +++---- .../method/MethodValidationResult.java | 4 ++-- .../MockitoBeanOverrideHandlerTests.java | 2 +- .../web/context/ContextLoaderListener.java | 4 ++-- .../function/server/RouterFunctions.java | 24 +++++++++---------- .../web/servlet/function/RouterFunctions.java | 24 +++++++++---------- .../web/servlet/function/ServerResponse.java | 8 +++---- ...ResponseBodyEmitterReturnValueHandler.java | 2 +- 10 files changed, 42 insertions(+), 42 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverrides.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverrides.java index d9d9e6c121..41321805db 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverrides.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverrides.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -87,7 +87,7 @@ public class MethodOverrides { /** * Return the override for the given method, if any. - * @param method method to check for overrides for + * @param method the method to check for overrides for * @return the method override, or {@code null} if none */ @Nullable diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodReplacer.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodReplacer.java index e4e5df879e..e8d844db7d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodReplacer.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodReplacer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ public interface MethodReplacer { * @param obj the instance we're reimplementing the method for * @param method the method to reimplement * @param args arguments to the method - * @return return value for the method + * @return the return value for the method */ Object reimplement(Object obj, Method method, Object[] args) throws Throwable; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java index 37f9094639..25dcc716ff 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -405,10 +405,10 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader /** * Get all property values, given a prefix (which will be stripped) * and add the bean they define to the factory with the given name. - * @param beanName name of the bean to define + * @param beanName the name of the bean to define * @param map a Map containing string pairs - * @param prefix prefix of each entry, which will be stripped - * @param resourceDescription description of the resource that the + * @param prefix the prefix of each entry, which will be stripped + * @param resourceDescription the description of the resource that the * Map came from (for logging purposes) * @throws BeansException if the bean definition could not be parsed or registered */ diff --git a/spring-context/src/main/java/org/springframework/validation/method/MethodValidationResult.java b/spring-context/src/main/java/org/springframework/validation/method/MethodValidationResult.java index 69ff06f55c..9e79e2a036 100644 --- a/spring-context/src/main/java/org/springframework/validation/method/MethodValidationResult.java +++ b/spring-context/src/main/java/org/springframework/validation/method/MethodValidationResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -87,7 +87,7 @@ public interface MethodValidationResult { * on their fields and properties. * @see #getValueResults() * @see #getBeanResults() - * @deprecated deprecated in favor of {@link #getParameterValidationResults()} + * @deprecated As of Spring Framework 6.2, in favor of {@link #getParameterValidationResults()} */ @Deprecated(since = "6.2", forRemoval = true) default List getAllValidationResults() { diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideHandlerTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideHandlerTests.java index 466bcd93e3..1875e2e2d6 100644 --- a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideHandlerTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideHandlerTests.java @@ -126,7 +126,7 @@ class MockitoBeanOverrideHandlerTests { /** * Since the "field name as fallback qualifier" is not available for an annotated class, * what would seem to be "equivalent" handlers are actually not considered "equal" when - * the the lookup is "by type". + * the lookup is "by type". */ @Test // gh-33925 void isNotEqualToWithSameByTypeLookupMetadataFromFieldAndClassLevel() { diff --git a/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java b/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java index e065e41526..9a4101d847 100644 --- a/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java +++ b/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -91,7 +91,7 @@ public class ContextLoaderListener extends ContextLoader implements ServletConte *
  • {@code ServletContext} and {@code ServletConfig} objects will be delegated to * the application context
  • *
  • {@link #customizeContext} will be called
  • - *
  • Any {@link org.springframework.context.ApplicationContextInitializer ApplicationContextInitializer org.springframework.context.ApplicationContextInitializer ApplicationContextInitializers} + *
  • Any {@link org.springframework.context.ApplicationContextInitializer ApplicationContextInitializers} * specified through the "contextInitializerClasses" init-param will be applied.
  • *
  • {@link org.springframework.context.ConfigurableApplicationContext#refresh refresh()} will be called
  • * diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java index d2b81a2278..8331ceb0f5 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -153,7 +153,7 @@ public abstract class RouterFunctions { * Resource resource = new ClassPathResource("static/index.html") * RouterFunction<ServerResponse> resources = RouterFunctions.resource(path("/api/**").negate(), resource); * - * @param predicate predicate to match + * @param predicate the predicate to match * @param resource the resources to serve * @return a router function that routes to a resource * @since 6.1.4 @@ -169,7 +169,7 @@ public abstract class RouterFunctions { * Resource resource = new ClassPathResource("static/index.html") * RouterFunction<ServerResponse> resources = RouterFunctions.resource(path("/api/**").negate(), resource); * - * @param predicate predicate to match + * @param predicate the predicate to match * @param resource the resources to serve * @param headersConsumer provides access to the HTTP headers for served resources * @return a router function that routes to a resource @@ -384,7 +384,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code GET} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code GET} requests that * match {@code predicate} * @return this builder @@ -436,7 +436,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code HEAD} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code HEAD} requests that * match {@code predicate} * @return this builder @@ -479,7 +479,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code POST} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code POST} requests that * match {@code predicate} * @return this builder @@ -530,7 +530,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code PUT} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code PUT} requests that * match {@code predicate} * @return this builder @@ -581,7 +581,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code PATCH} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code PATCH} requests that * match {@code predicate} * @return this builder @@ -632,7 +632,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code DELETE} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code DELETE} requests that * match {@code predicate} * @return this builder @@ -675,7 +675,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code OPTIONS} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code OPTIONS} requests that * match {@code predicate} * @return this builder @@ -735,7 +735,7 @@ public abstract class RouterFunctions { * Resource resource = new ClassPathResource("static/index.html") * RouterFunction<ServerResponse> resources = RouterFunctions.resource(path("/api/**").negate(), resource); * - * @param predicate predicate to match + * @param predicate the predicate to match * @param resource the resources to serve * @return a router function that routes to a resource * @since 6.1.4 @@ -749,7 +749,7 @@ public abstract class RouterFunctions { * Resource resource = new ClassPathResource("static/index.html") * RouterFunction<ServerResponse> resources = RouterFunctions.resource(path("/api/**").negate(), resource); * - * @param predicate predicate to match + * @param predicate the predicate to match * @param resource the resources to serve * @param headersConsumer provides access to the HTTP headers for served resources * @return a router function that routes to a resource diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java index 536f3b43d0..f2ea64ea97 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -136,7 +136,7 @@ public abstract class RouterFunctions { * Resource resource = new ClassPathResource("static/index.html") * RouterFunction<ServerResponse> resources = RouterFunctions.resource(path("/api/**").negate(), resource); * - * @param predicate predicate to match + * @param predicate the predicate to match * @param resource the resources to serve * @return a router function that routes to a resource * @since 6.1.4 @@ -152,7 +152,7 @@ public abstract class RouterFunctions { * Resource resource = new ClassPathResource("static/index.html") * RouterFunction<ServerResponse> resources = RouterFunctions.resource(path("/api/**").negate(), resource); * - * @param predicate predicate to match + * @param predicate the predicate to match * @param resource the resources to serve * @param headersConsumer provides access to the HTTP headers for served resources * @return a router function that routes to a resource @@ -298,7 +298,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code GET} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code GET} requests that * match {@code predicate} * @return this builder @@ -350,7 +350,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code HEAD} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code HEAD} requests that * match {@code predicate} * @return this builder @@ -393,7 +393,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code POST} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code POST} requests that * match {@code predicate} * @return this builder @@ -444,7 +444,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code PUT} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code PUT} requests that * match {@code predicate} * @return this builder @@ -495,7 +495,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code PATCH} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code PATCH} requests that * match {@code predicate} * @return this builder @@ -546,7 +546,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code DELETE} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code DELETE} requests that * match {@code predicate} * @return this builder @@ -589,7 +589,7 @@ public abstract class RouterFunctions { /** * Adds a route to the given handler function that handles all HTTP {@code OPTIONS} requests * that match the given predicate. - * @param predicate predicate to match + * @param predicate the predicate to match * @param handlerFunction the handler function to handle all {@code OPTIONS} requests that * match {@code predicate} * @return this builder @@ -648,7 +648,7 @@ public abstract class RouterFunctions { * Resource resource = new ClassPathResource("static/index.html") * RouterFunction<ServerResponse> resources = RouterFunctions.resource(path("/api/**").negate(), resource); * - * @param predicate predicate to match + * @param predicate the predicate to match * @param resource the resources to serve * @return a router function that routes to a resource * @since 6.1.4 @@ -662,7 +662,7 @@ public abstract class RouterFunctions { * Resource resource = new ClassPathResource("static/index.html") * RouterFunction<ServerResponse> resources = RouterFunctions.resource(path("/api/**").negate(), resource); * - * @param predicate predicate to match + * @param predicate the predicate to match * @param resource the resources to serve * @param headersConsumer provides access to the HTTP headers for served resources * @return a router function that routes to a resource diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java index 2f4356e380..47eab85dca 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java @@ -290,7 +290,7 @@ public interface ServerResponse { * .send("Hello World!")); * } * - * @param consumer consumer that will be provided with an event builder + * @param consumer the consumer that will be provided with an event builder * @return the server-side event response * @since 5.3.2 * @see Server-Sent Events @@ -319,8 +319,8 @@ public interface ServerResponse { * .send("Hello World!")); * } * - * @param consumer consumer that will be provided with an event builder - * @param timeout maximum time period to wait before timing out + * @param consumer the consumer that will be provided with an event builder + * @param timeout maximum time period to wait before timing out * @return the server-side event response * @since 5.3.2 * @see Server-Sent Events @@ -338,7 +338,7 @@ public interface ServerResponse { /** * Add the given header value(s) under the given name. - * @param headerName the header name + * @param headerName the header name * @param headerValues the header value(s) * @return this builder * @see HttpHeaders#add(String, String) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java index 26cc1e8811..d9f3ca5e5b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java @@ -135,7 +135,7 @@ public class ResponseBodyEmitterReturnValueHandler implements HandlerMethodRetur * @param executor for blocking I/O writes of items emitted from reactive types * @param manager for detecting streaming media types * @param viewResolvers resolvers for fragment stream rendering - * @param localeResolver localeResolver for fragment stream rendering + * @param localeResolver the {@link LocaleResolver} for fragment stream rendering * @since 6.2 */ public ResponseBodyEmitterReturnValueHandler( From 7095f4cb664f7fcf033dde84325eda83d67ece70 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Mon, 14 Apr 2025 11:25:40 +0200 Subject: [PATCH 4/4] Use proper casing for parameter and variable names --- .../springframework/core/test/tools/ResourceFiles.java | 8 ++++---- .../r2dbc/connection/R2dbcTransactionManager.java | 6 +++--- .../web/util/pattern/PathPatternTests.java | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/spring-core-test/src/main/java/org/springframework/core/test/tools/ResourceFiles.java b/spring-core-test/src/main/java/org/springframework/core/test/tools/ResourceFiles.java index 1a53e92277..8648fc5fb0 100644 --- a/spring-core-test/src/main/java/org/springframework/core/test/tools/ResourceFiles.java +++ b/spring-core-test/src/main/java/org/springframework/core/test/tools/ResourceFiles.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -81,11 +81,11 @@ public final class ResourceFiles implements Iterable { /** * Return a new {@link ResourceFiles} instance that merges files from * another {@link ResourceFiles} instance. - * @param ResourceFiles the instance to merge + * @param resourceFiles the instance to merge * @return a new {@link ResourceFiles} instance containing merged content */ - public ResourceFiles and(ResourceFiles ResourceFiles) { - return new ResourceFiles(this.files.and(ResourceFiles.files)); + public ResourceFiles and(ResourceFiles resourceFiles) { + return new ResourceFiles(this.files.and(resourceFiles.files)); } @Override diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java index d7dd814f6e..96d332d8db 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -296,7 +296,7 @@ public class R2dbcTransactionManager extends AbstractReactiveTransactionManager } @Override - protected Mono doCommit(TransactionSynchronizationManager TransactionSynchronizationManager, + protected Mono doCommit(TransactionSynchronizationManager synchronizationManager, GenericReactiveTransaction status) { ConnectionFactoryTransactionObject txObject = (ConnectionFactoryTransactionObject) status.getTransaction(); @@ -308,7 +308,7 @@ public class R2dbcTransactionManager extends AbstractReactiveTransactionManager } @Override - protected Mono doRollback(TransactionSynchronizationManager TransactionSynchronizationManager, + protected Mono doRollback(TransactionSynchronizationManager synchronizationManager, GenericReactiveTransaction status) { ConnectionFactoryTransactionObject txObject = (ConnectionFactoryTransactionObject) status.getTransaction(); diff --git a/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java b/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java index cdf9a475d9..ebaeb84863 100644 --- a/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1211,8 +1211,8 @@ class PathPatternTests { private void checkNoMatch(String uriTemplate, String path) { PathPatternParser p = new PathPatternParser(); PathPattern pattern = p.parse(uriTemplate); - PathContainer PathContainer = toPathContainer(path); - assertThat(pattern.matches(PathContainer)).isFalse(); + PathContainer pathContainer = toPathContainer(path); + assertThat(pattern.matches(pathContainer)).isFalse(); } private PathPattern.PathMatchInfo checkCapture(String uriTemplate, String path, String... keyValues) {