Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

YamlPropertiesFactoryBean incorrect flatten nested map to properties #34285

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

remeio
Copy link
Contributor

@remeio remeio commented Jan 19, 2025

To fix issue #27020.

For the method org.springframework.beans.factory.config.YamlProcessor#getFlattenedMap before this PR:

  • When the key is start with [, will return path + key as map key.
  • Otherwise, will return path + '.' + key as map key.
if (key.startsWith("[")) {
	key = path + key;
}
else {
	key = path + '.' + key;
}

For the method org.springframework.beans.factory.config.YamlProcessor#getFlattenedMap after this PR:

  • When the key is start with [ or end with ], will return path + '[' + key + ']' as map key.
  • Otherwise, will return path + '.' + key as map key.
  • And when the key is indexed key at Collection like [0], will return path + key as map key.

For the method org.springframework.beans.factory.config.YamlProcessor#asMap after this PR:
Change result.put("[" + key.toString() + "]", value); to result.put(key.toString(), value); on asMap.

And the test case you can see:

root:
  webservices:
    "[domain.test:8080]":
      - username: foo
        password: bar
# Before this PR:
# root.webservices[domain.test:8080][0].username=foo
# root.webservices[domain.test:8080][0].password=bar
# After this PR:
# root.webservices[[domain.test:8080]][0].username=foo
# root.webservices[[domain.test:8080]][0].password=bar

indexed:
  "[0]": foo
  "[1]": bar
indexed2:
  - "[a]": foo
    "[b]": bar
# Before this PR:
# indexed[0]=foo
# indexed[1]=bar
# indexed2[0][a]=foo
# indexed2[0][b]=bar
# After this PR:
# indexed[[0]]=foo
# indexed[[1]]=bar
# indexed2[0][[a]]=foo
# indexed2[0][[b]]=bar

only-left-bracket:
  "[/key1/": foo
only-right-bracket:
  "/key1/]": foo
special-bracket:
  "][/key1/][": foo
# Before this PR:
# only-left-bracket[/key1/=foo
# only-right-bracket./key1/]=foo
# special-bracket.][/key1/][=foo
# After this PR:
# only-left-bracket[[/key1/]=foo
# only-right-bracket[/key1/]]=foo
# special-bracket.][/key1/][=foo


number-key:
  1: foo
# Before this PR:
# number-key[1]=bar
# After this PR:
# number-key.1=foo

By the way, org.springframework.beans.factory.config.YamlMapFactoryBean#getObject result is:

# Before this PR & After this PR:
# root={webservices={[domain.test:8080]=[{username=foo, password=bar}]}}
# indexed={[0]=foo, [1]=bar}
# indexed2=[{[a]=foo, [b]=bar}]
# only-left-bracket={[/key1/=foo}
# only-right-bracket={/key1/]=foo}
# special-bracket={][/key1/][=foo}

# Before this PR:
# number-key={[1]=foo}
# After this PR:
# number-key={1=foo}

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 19, 2025
@remeio
Copy link
Contributor Author

remeio commented Jan 19, 2025

This PR just is a try, I submit the test case for []. It's important to explain what result is correct for this test case. Maybe you can fill it with:

root:
  webservices:
    "[domain.test:8080]":
      - username: foo
        password: bar
# properties should be?
# map should be?

indexed:
  "[0]": foo
  "[1]": bar
indexed2:
  - "[a]": foo
    "[b]": bar
# properties should be?
# map should be?

only-left-bracket:
  "[/key1/": foo
only-right-bracket:
  "/key1/]": foo
special-bracket:
  "][/key1/][": foo
# properties should be?
# map should be?

number-key:
  1: foo
# properties should be?
# map should be?

By the way, If We want to use @ConfigurationProperties on Spring Boot, we need to config yaml file with following the document Binding Maps. We can see:

When binding to Map properties you may need to use a special bracket notation so that the original key value is preserved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged or decided on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants