Spring integration payload-expression: SPEL expression with args - spring

I want to have a payload-expression in spring integration that does this:
#{T(java.util.Arrays).asList(#args[0],#args[1],#args[2])}
I can't get the args values to be taken as args. What's the proper what to do this?
Thanks

The #{...} syntax is for SpEL expressions evaluated once, while the context is initialized.
In this case, you simply need
payload-expression="T(java.util.Arrays).asList(#args[0],#args[1],#args[2])"

Related

Spring Expressions, what does it mean value="{someName}"

I am working with a Spring Boot Application that uses SpEl , it has some Redis annotations and it calls my attention the use of brackets on some expressions, i.e.:
#Cacheable(value = "{mycache}", key = "#param")
I can tell the SpEl expression when using # is to refer to the passed param, but for the first part "{myCache}" I am not sure what is the purpose of the braces.

How do I set Spring properties in run configuration in Intellij

I have the following code...
#Service
public class PropertiesService {
...
#Value("external.config.active") private String useExternalConfig
So in intellij I set the VM Options to...
-Dexternal.config.active=true
But when I debug in the application this.useExternalConfig.equals("external.config.active") is true.
What do I have to do to set a Spring property in the run configuration for IJ
Update I see it being supplied in the java command...
/.../java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:53192,suspend=y,server=n -Dexternal.config.active=true -javaagent:/.../Caches/IdeaIC2018.1/groovyHotSwap/gragent.jar -javaagent:/.../Caches/IdeaIC2018.1/captureAgent/debugger-agent.jar=file:/private/var/folders/3d/5f6dvvs573zg3ydvxbd0b0h40000gn/T/capture2.props -Dfile.encoding=UTF-8 -classpath
#Value takes a value expression ${...} or a SpEL expression #{...} as you haven't provided any of those the value as is will be used. To substitute a property you can use a value expression ${name.of.property}.
Or if you really like hardcore you can use SpEL #{#environment.getProperty('name.of.property')}. You see the value expression is easier.
This does seem to work...
#Value("${external.config.active}")
based on...
The actual value expression: e.g. "#{systemProperties.myProp}".
This is strange so if anyone can explain it further they get the check.

How to disable interpolation of property values in property placeholders

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?
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}
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}

Injecting Spring Spel Expressions into bean properties

How can I inject a String meant to be a spel expression into an app context bean property without having the context interpret the string property as a spel resolvable value.
<bean id="x" p:spelExpression="${#code}/${#value}"/>
I want the the class's setter property to take a string argument and creates a reusable SpelExpression as a private property of the bean, however, the spring application context appears to be recognizing the #variableName as spel expressions and attempting to interpret the expression at initialization time.
I find Spel interpretation to be very useful, but would like to to use spel internally as well, with expression injection into my own beans.
Is it possible to disable the Spel Interpretation of for a bean, or even for a whole context file (maybe with some namespace shenanigans) without having to disable or modify spel expression resolution for the whole application context.
The #{...} are markers for spel interpreter in xml context.
I don't undestand : ${#code}/${#value}. Good is #{code/value}, as I understand things, if code and value are id.
So, if you want a spel expression without interpret it, put string code/value in xml.

Can Spring EL (SpEL) be configured to ignore null objects in the middle of an expression

If I have the expression: obj1.obj2.obj3
And obj2 is null, then expression fails with an exception. Is there any way to configure SpEL to just return null?
You should use safe navigation operator that is ?. (in your example that'd be obj1?.obj2?.obj3) to avoid nasty NullPointerException while navigating graph of beans.
You can find detailed explanation and some examples in chapter 6.5.15 Safe Navigation operator of reference

Resources