spring-projects / spring-boot

Spring Boot
https://spring.io/projects/spring-boot
Apache License 2.0
74.57k stars 40.55k forks source link

Allow map binding to work with unescaped characters #13404

Open yygnay opened 6 years ago

yygnay commented 6 years ago

Spring boot version: 2.0.2 (1.5.13 is normal)

Problem Description:

If the map key is with “/”, it cannot be parsed normally. Others are normal.

Example:

application.yml 

shiro:
  testMap:
    /test1: test1
    /test2: test2

Configuration class

@Data
@ConfigurationProperties(prefix="shiro")
public class ShiroProperties {
    private Map<String,String> testMap;
}

Test class

@Transactional
@RunWith(SpringRunner.class)
@SpringBootTest(classes=DataManage.class)
public class ShiroTest extends BaseTransactionalTest{

    @Autowired
    private ShiroProperties shiroConfig;

    @Test
    public void read() {
        System.out.println(shiroConfig.toString());
    }

}

console info:

ShiroProperties(testMap={test1=test1, test2=test2})
philwebb commented 6 years ago

The new binder is much stricter about property names which means you need to surround them in square brackets. Try the following:

shiro:
  testMap:
    "[/test1]": test1
    "[/test2]": test2
philwebb commented 6 years ago

I'm wonder if there's any way we can make this more user friendly. I've flagged the issue for discussion at our next call.

yygnay commented 6 years ago

Thank you! According to your suggestion it can be used normally, I hope there are relevant examples in the official document...

mbhave commented 6 years ago

We might be able to get the original key in the EntryBinder.

edysli commented 6 years ago

This also tripped me up while migrating to 2.0 because I have URLs as keys, something like:

myapp
  serviceUrls:
    'https://example.org/test': 'https://test.example.org/Endpoint'

and it used to work fine with 1.5. After finding this issue, I changed this map to:

'[https://example.org/test]': 'https://test.example.org/Endpoint'

and now it parses correctly. Please document this explicitly in the migration guide or reference doc.

snicoll commented 6 years ago

@edysli there is already an issue for that #13506, with a reference right above your comment.

edysli commented 6 years ago

@snicoll Yeah I saw it, I just didn't know which one was best to host my "me too" example so I picked the lowest id... :wink: I can move my comment over to #13506, if that's less messy.

Chatom commented 5 years ago

Hi, it indeed works well with the use of brackets, but it is quite unnatural to do so. I'd understand the use of quotes (even if they're not necessary in yaml syntax) but brackets seems a bit too much. Another problem is that the mapping to the cleaned string without any warning can easily lead to errors if the config is not checked properly...

wilkinsona commented 5 years ago

@Chatom We're aware that there's some room for improvement here. That's why this issue remains open.

maraswrona commented 4 years ago

Any idea when this could be improved? Is there some better way around this (other than using brackets) ?

wilkinsona commented 4 years ago

@maraswrona The issue is in the 2.x milestone which means it'll be considered for inclusion in 2.3.

kdowbecki commented 4 years ago

I'd really prefer the binder to fail fast with an exception when it discovers unescaped property names. Currently 2.2.1 silently modifies the property name by removing special characters which is a nightmare to debug.

pablocavalieri commented 3 years ago

The new binder is much stricter about property names which means you need to surround them in square brackets. Try the following:

shiro:
  testMap:
    "[/test1]": test1
    "[/test2]": test2

Is there a way to scape the square brackets? I need my Map key to be some value[value between square brackets]

philwebb commented 3 years ago

@pablocavalieri I believe you can do this:

testMap:
  "[some value[value between square brackets]]": "test"