Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable interpolation of property values in property placeholders

Tags:

spring

I'm using Spring 3 and Spring's property-placeholders in my application context:

<context:property-placeholder location="my.properties"/>

my.properties contains:

key1=value1
key2=some JSP code ${some-model-attr}

The issue is, the values in my.properties are also evaluated against the placeholders, but in my case the values contain JSP EL, which causes "property not found" errors during Spring initialization:

java.lang.IllegalArgumentException: Could not resolve placeholder 'some-model-attr'

So far I have this workaround, but it's ugly:

key1=value1
key2=some JSP code #{'$'}{some-model-attr}

Hence my question:

Is it possible to tell Spring not to interpolate property placeholder values, or, in other words, not to evaluate placeholders recursively?

like image 926
rustyx Avatar asked Feb 05 '12 22:02

rustyx


People also ask

What 2 types of file formats can use to inject properties into the Spring environment object?

You can use properties files, YAML files, environment variables and command-line arguments to externalize configuration.

How do I set environment-specific properties in Spring boot?

Environment-Specific Properties File. If we need to target different environments, there's a built-in mechanism for that in Boot. We can simply define an application-environment. properties file in the src/main/resources directory, and then set a Spring profile with the same environment name.

How can we read properties file in Spring boot using environment?

Read properties Using the Environment Object One of the easiest ways to read a property from the application. properties file is by autowiring an Environment object. All you need to do is to use the @Autowired annotation. It is called dependency injection.


2 Answers

It looks like it isn't possible to tell Spring not to recursively evaluate placeholders.

The placeholders are evaluated by org.springframework.util.PropertyPlaceholderHelper which (in Spring 3) contains the following line:

    // Recursive invocation, parsing placeholders contained in the placeholder key.
    placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);

So the recursive call is hard-coded into the evaluation.

However I think you could change the default prefix and suffix for placeholders so that you use a different syntax for Spring placeholders. <context:property-placeholder> is just a convenient way of constructing the org.springframework.beans.factory.config.PropertyPlaceholderConfigurer class, and that class has methods setPlaceholderPrefix() and setPlaceholderSuffix(). You could use those methods to change the syntax of the Spring placeholders to something like:

$[property]

instead of

${property}

Then I expect Spring won't parse your JSP properties any more because they're in a different syntax:

key2=some JSP code ${some-model-attr}
like image 171
gutch Avatar answered Oct 13 '22 04:10

gutch


As a workaround you can use SpEL expression templating. For example:

key2=some JSP code $#{'{some-model-attr}'}

This works because Spring no longer sees the configured property placeholder prefix of ${. However, the SpEL expression evaluates to the String concatenation of:

'some JSP code $' + '{some-model-attr}' 

which is the same as

some JSP code ${some-model-attr}
like image 36
Rob Winch Avatar answered Oct 13 '22 05:10

Rob Winch