Skip to content

Commit cdbb7f4

Browse files
committed
Do not ignore null/empty values from SPRING_APPLICATION_JSON
Fixes gh-21542
1 parent ccffd50 commit cdbb7f4

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,11 @@ You can also supply the JSON as a JNDI variable, as follows: `java:comp/env/spri
426426
====
427427

428428

429+
NOTE: Although `null` values from the JSON will be added to the resulting property source, the `PropertySourcesPropertyResolver` treats `null` properties as missing values.
430+
This means that the JSON cannot override properties from lower order property sources with a `null` value.
431+
432+
433+
429434

430435
[[boot-features-external-config-random-values]]
431436
=== Configuring Random Values

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessor.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@
3838
import org.springframework.core.env.PropertySource;
3939
import org.springframework.core.env.StandardEnvironment;
4040
import org.springframework.util.ClassUtils;
41+
import org.springframework.util.CollectionUtils;
4142
import org.springframework.util.StringUtils;
4243
import org.springframework.web.context.support.StandardServletEnvironment;
4344

@@ -123,9 +124,17 @@ private void flatten(String prefix, Map<String, Object> result, Map<String, Obje
123124
@SuppressWarnings("unchecked")
124125
private void extract(String name, Map<String, Object> result, Object value) {
125126
if (value instanceof Map) {
127+
if (CollectionUtils.isEmpty((Map<?, ?>) value)) {
128+
result.put(name, value);
129+
return;
130+
}
126131
flatten(name, result, (Map<String, Object>) value);
127132
}
128133
else if (value instanceof Collection) {
134+
if (CollectionUtils.isEmpty((Collection<?>) value)) {
135+
result.put(name, value);
136+
return;
137+
}
129138
int index = 0;
130139
for (Object object : (Collection<Object>) value) {
131140
extract(name + "[" + index + "]", result, object);

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessorTests.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
1717
package org.springframework.boot.env;
1818

1919
import java.util.Collections;
20+
import java.util.Map;
2021

2122
import org.junit.jupiter.api.Test;
2223

@@ -26,6 +27,7 @@
2627
import org.springframework.core.env.MapPropertySource;
2728
import org.springframework.core.env.PropertySource;
2829
import org.springframework.core.env.StandardEnvironment;
30+
import org.springframework.mock.env.MockPropertySource;
2931
import org.springframework.test.context.support.TestPropertySourceUtils;
3032
import org.springframework.web.context.support.StandardServletEnvironment;
3133

@@ -170,6 +172,39 @@ void propertySourceOrderingWhenMultipleServletSpecificPropertySources() {
170172
assertThat(this.environment.getPropertySources()).containsSequence(custom, json, servlet, jndi);
171173
}
172174

175+
@Test
176+
void nullValuesShouldBeAddedToPropertySource() {
177+
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
178+
"SPRING_APPLICATION_JSON={\"foo\":null}");
179+
this.processor.postProcessEnvironment(this.environment, null);
180+
assertThat(this.environment.containsProperty("foo")).isTrue();
181+
}
182+
183+
@Test
184+
void emptyValuesForCollectionShouldNotBeIgnored() {
185+
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
186+
"SPRING_APPLICATION_JSON={\"foo\":[]}");
187+
MockPropertySource source = new MockPropertySource();
188+
source.setProperty("foo", "bar");
189+
this.environment.getPropertySources().addLast(source);
190+
assertThat(this.environment.resolvePlaceholders("${foo}")).isEqualTo("bar");
191+
this.environment.getPropertySources().addLast(source);
192+
this.processor.postProcessEnvironment(this.environment, null);
193+
assertThat(this.environment.resolvePlaceholders("${foo}")).isEmpty();
194+
}
195+
196+
@Test
197+
@SuppressWarnings("unchecked")
198+
void emptyMapValuesShouldNotBeIgnored() {
199+
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
200+
"SPRING_APPLICATION_JSON={\"foo\":{}}");
201+
MockPropertySource source = new MockPropertySource();
202+
source.setProperty("foo.baz", "bar");
203+
this.environment.getPropertySources().addLast(source);
204+
this.processor.postProcessEnvironment(this.environment, null);
205+
assertThat(this.environment.getProperty("foo", Map.class)).isEmpty();
206+
}
207+
173208
private void testServletPropertySource(String servletPropertySourceName) {
174209
this.environment.getPropertySources().addFirst(getPropertySource(servletPropertySourceName, "servlet"));
175210
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,

0 commit comments

Comments
 (0)