mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-10-04 00:09:01 +00:00
Merge pull request #49152 from osvetlik
* pr/49152: Polish "Bind `Optional` value object parameters as empty rather than `null`" Bind `Optional` value object parameters as empty rather than `null` Closes gh-49152
This commit is contained in:
+7
-6
@@ -98,14 +98,12 @@ final class BindConverter {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> @Nullable T convert(@Nullable Object source, ResolvableType targetType, Annotation... targetAnnotations) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
return (T) convert(source, TypeDescriptor.forObject(source),
|
||||
new ResolvableTypeDescriptor(targetType, targetAnnotations));
|
||||
TypeDescriptor sourceType = (source != null) ? TypeDescriptor.forObject(source) : null;
|
||||
return (T) convert(source, sourceType, new ResolvableTypeDescriptor(targetType, targetAnnotations));
|
||||
}
|
||||
|
||||
private @Nullable Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
private @Nullable Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType,
|
||||
TypeDescriptor targetType) {
|
||||
ConversionException failure = null;
|
||||
for (ConversionService delegate : this.delegates) {
|
||||
try {
|
||||
@@ -119,6 +117,9 @@ final class BindConverter {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
throw (failure != null) ? failure : new ConverterNotFoundException(sourceType, targetType);
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -61,6 +61,7 @@ import org.springframework.util.Assert;
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
* @author Scott Frederick
|
||||
* @author Ondřej Světlík
|
||||
*/
|
||||
class ValueObjectBinder implements DataObjectBinder {
|
||||
|
||||
@@ -132,7 +133,7 @@ class ValueObjectBinder implements DataObjectBinder {
|
||||
return convertDefaultValue(context.getConverter(), defaultValue, type, annotations);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return context.getConverter().convert(null, type);
|
||||
}
|
||||
|
||||
private <T> @Nullable T convertDefaultValue(BindConverter converter, String[] defaultValue, ResolvableType type,
|
||||
|
||||
+28
@@ -50,6 +50,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
* @author Phillip Webb
|
||||
* @author Pavel Anisimov
|
||||
* @author Yanming Zhou
|
||||
* @author Ondřej Světlík
|
||||
*/
|
||||
class ValueObjectBinderTests {
|
||||
|
||||
@@ -326,6 +327,25 @@ class ValueObjectBinderTests {
|
||||
assertThat(bound.getOptionalValue()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void bindWhenOptionalParameterWithNoValueForPrimitiveShouldReturnEmptyInstance() {
|
||||
RecordPropertiesWithOptional bound = this.binder.bindOrCreate("foo",
|
||||
Bindable.of(RecordPropertiesWithOptional.class));
|
||||
assertThat(bound.property1()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void bindWhenOptionalParameterInNestedWithNoValueForPrimitiveShouldReturnEmptyInstance() {
|
||||
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
|
||||
source.put("foo.nested.property2", "str");
|
||||
this.sources.add(source);
|
||||
RecordPropertiesWithOptionalInNestedRecord bound = this.binder.bindOrCreate("foo",
|
||||
Bindable.of(RecordPropertiesWithOptionalInNestedRecord.class));
|
||||
assertThat(bound.nested()).isNotNull();
|
||||
assertThat(bound.nested().property1()).isNotNull().isEmpty();
|
||||
assertThat(bound.nested().property2()).isEqualTo("str");
|
||||
}
|
||||
|
||||
@Test
|
||||
void bindWhenEnumParameterWithEmptyDefaultValueShouldThrowException() {
|
||||
assertThatExceptionOfType(BindException.class)
|
||||
@@ -902,6 +922,14 @@ class ValueObjectBinderTests {
|
||||
@DefaultValue("default-value-2") String property2) {
|
||||
}
|
||||
|
||||
record RecordPropertiesWithOptional(Optional<String> property1) {
|
||||
}
|
||||
|
||||
record RecordPropertiesWithOptionalInNestedRecord(NestedRecord nested) {
|
||||
record NestedRecord(Optional<String> property1, String property2) {
|
||||
}
|
||||
}
|
||||
|
||||
static class NonExtractableParameterName {
|
||||
|
||||
private @Nullable String value;
|
||||
|
||||
Reference in New Issue
Block a user