From f8a3077da978f1651940d6e8519087237f43348c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20H=C3=A4nel?= Date: Sun, 30 Mar 2025 20:28:12 +0200 Subject: [PATCH 1/3] Fix typo in Bean Validation section of reference manual MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fixes a minor typo in the "Java Bean Validation - Customizing Validation Errors" section of the reference manual. Closes gh-34686 Signed-off-by: Tobias Hänel --- .../modules/ROOT/pages/core/validation/beanvalidation.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc index 5d087e5641..f5d83d4ad7 100644 --- a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc +++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc @@ -399,7 +399,7 @@ A `ConstraintViolation` on the `degrees` method parameter is adapted to a `MessageSourceResolvable` with the following: - Error codes `"Max.myService#addStudent.degrees"`, `"Max.degrees"`, `"Max.int"`, `"Max"` -- Message arguments "degrees2 and 2 (the field name and the constraint attribute) +- Message arguments "degrees" and 2 (the field name and the constraint attribute) - Default message "must be less than or equal to 2" To customize the above default message, you can add a property such as: From dcb9383ba1239aa949983f5ef9e6dcf9cad4e98a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Mon, 31 Mar 2025 11:15:40 +0200 Subject: [PATCH 2/3] Add a requiredExchange extension to RestClient Closes gh-34692 --- .../web/client/RestClientExtensions.kt | 16 +++++++++++-- .../web/client/RestClientExtensionsTests.kt | 23 ++++++++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/spring-web/src/main/kotlin/org/springframework/web/client/RestClientExtensions.kt b/spring-web/src/main/kotlin/org/springframework/web/client/RestClientExtensions.kt index 12092af8df..5159993951 100644 --- a/spring-web/src/main/kotlin/org/springframework/web/client/RestClientExtensions.kt +++ b/spring-web/src/main/kotlin/org/springframework/web/client/RestClientExtensions.kt @@ -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. @@ -18,6 +18,8 @@ package org.springframework.web.client import org.springframework.core.ParameterizedTypeReference import org.springframework.http.ResponseEntity +import org.springframework.web.client.RestClient.RequestHeadersSpec +import org.springframework.web.client.RestClient.RequestHeadersSpec.ExchangeFunction /** * Extension for [RestClient.RequestBodySpec.body] providing a `bodyWithType(...)` variant @@ -51,6 +53,15 @@ inline fun RestClient.ResponseSpec.body(): T? = inline fun RestClient.ResponseSpec.requiredBody(): T = body(object : ParameterizedTypeReference() {}) ?: throw NoSuchElementException("Response body is required") +/** + * Extension for [RestClient.RequestHeadersSpec.exchange] providing a `requiredExchange(...)` variant with a + * non-nullable return value. + * @throws NoSuchElementException if there is no response value + * @since 6.2.6 + */ +fun RequestHeadersSpec<*>.requiredExchange(exchangeFunction: ExchangeFunction, close: Boolean = true): T = + exchange(exchangeFunction, close) ?: throw NoSuchElementException("Response value is required") + /** * Extension for [RestClient.ResponseSpec.toEntity] providing a `toEntity()` variant * leveraging Kotlin reified type parameters. This extension is not subject to type @@ -60,4 +71,5 @@ inline fun RestClient.ResponseSpec.requiredBody(): T = * @since 6.1 */ inline fun RestClient.ResponseSpec.toEntity(): ResponseEntity = - toEntity(object : ParameterizedTypeReference() {}) \ No newline at end of file + toEntity(object : ParameterizedTypeReference() {}) + diff --git a/spring-web/src/test/kotlin/org/springframework/web/client/RestClientExtensionsTests.kt b/spring-web/src/test/kotlin/org/springframework/web/client/RestClientExtensionsTests.kt index 6e91590166..e0a04a1602 100644 --- a/spring-web/src/test/kotlin/org/springframework/web/client/RestClientExtensionsTests.kt +++ b/spring-web/src/test/kotlin/org/springframework/web/client/RestClientExtensionsTests.kt @@ -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. @@ -19,9 +19,12 @@ package org.springframework.web.client import io.mockk.every import io.mockk.mockk import io.mockk.verify +import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.springframework.core.ParameterizedTypeReference +import org.springframework.http.HttpRequest +import org.springframework.web.client.RestClient.RequestHeadersSpec /** * Mock object based tests for [RestClient] Kotlin extensions @@ -59,6 +62,24 @@ class RestClientExtensionsTests { assertThrows { responseSpec.requiredBody() } } + @Test + fun `RequestHeadersSpec#requiredExchange`() { + val foo = Foo() + every { requestBodySpec.exchange(any>(), any()) } returns foo + val exchangeFunction: (HttpRequest, RequestHeadersSpec.ConvertibleClientHttpResponse) -> Foo? = + { request, response -> foo } + val value = requestBodySpec.requiredExchange(exchangeFunction) + assertThat(value).isEqualTo(foo) + } + + @Test + fun `RequestHeadersSpec#requiredExchange with null response throws NoSuchElementException`() { + every { requestBodySpec.exchange(any>(), any()) } returns null + val exchangeFunction: (HttpRequest, RequestHeadersSpec.ConvertibleClientHttpResponse) -> Foo? = + { request, response -> null } + assertThrows { requestBodySpec.requiredExchange(exchangeFunction) } + } + @Test fun `ResponseSpec#toEntity with reified type parameters`() { responseSpec.toEntity>() From 36d9357f94b73b39026e2fd0a555db6963ae1e04 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Mon, 31 Mar 2025 12:02:51 +0200 Subject: [PATCH 3/3] Fix Kotlin compilation errors --- .../springframework/web/client/RestClientExtensionsTests.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-web/src/test/kotlin/org/springframework/web/client/RestClientExtensionsTests.kt b/spring-web/src/test/kotlin/org/springframework/web/client/RestClientExtensionsTests.kt index e0a04a1602..703398e2c4 100644 --- a/spring-web/src/test/kotlin/org/springframework/web/client/RestClientExtensionsTests.kt +++ b/spring-web/src/test/kotlin/org/springframework/web/client/RestClientExtensionsTests.kt @@ -67,7 +67,7 @@ class RestClientExtensionsTests { val foo = Foo() every { requestBodySpec.exchange(any>(), any()) } returns foo val exchangeFunction: (HttpRequest, RequestHeadersSpec.ConvertibleClientHttpResponse) -> Foo? = - { request, response -> foo } + { _, _ -> foo } val value = requestBodySpec.requiredExchange(exchangeFunction) assertThat(value).isEqualTo(foo) } @@ -76,7 +76,7 @@ class RestClientExtensionsTests { fun `RequestHeadersSpec#requiredExchange with null response throws NoSuchElementException`() { every { requestBodySpec.exchange(any>(), any()) } returns null val exchangeFunction: (HttpRequest, RequestHeadersSpec.ConvertibleClientHttpResponse) -> Foo? = - { request, response -> null } + { _, _ -> null } assertThrows { requestBodySpec.requiredExchange(exchangeFunction) } }