Spring SpEL: how to write ternary operation in XML config? - spring

In my Spring XML config, I need to set a value to a specific property value depending on the value of another property.
I need something like this:
<bean id="myid" class="myclass">
<property name="myprop"
value="#{${property_a} == 'test-a' ? ${property_b} : 'anothervalue'}"
/>
I want myprop to be set the value of property_b if property_a is equal to "test-a", otherwise myprop must be set to "anothervalue".
property_a and property_b are both defined in my config.properties file.
Is it possible to write such a statement in XML SpEL?

<property name="myprop"
value="#{'${property_a}' == 'test-a' ? '${property_b}' : 'anothervalue' }" />
You have to ensure that the result of properties placeholder resolution is still literal. So, that's why we must wrap ${...} to ''.

Related

How to load value with dynamic key place holder in spring batch?

Spring Batch: How to get value from property file if key is generated dynamically from input parameter
propertyfile content:
my.table.book.bic.code=11111
my.table.news.bic.code=22222
Spring batch configuration
< property name="bicCodeValue" value="#{jobParameters['inputTable'] + '.bic.code'}" />
Where inputTable is input parameter for batch
inputTable = my.table.book
inputTable = my.table.news
I am not getting value from property file instead of value from property file I am getting only key in code "my.table.book.bic.code".
I need to update only in xml file like
< property name="bicCodeValue" value="#{jobParameters['inputTable'] + '.bic.code'}" / >
But this is not working.
You could inject an instance of
#Autowired
private Environment env;
and then do something like:
env.getProperty("my.table."+inputTable+".book.bic.code")
According to your properties, the SpEL expression jobParameters['inputTable'] should return a String value, so you can try to use the concat method in your expression:
<property name="bicCodeValue" value="#{jobParameters['inputTable'].concat('.bic.code')}" />
For more details about SpEL, please see here: https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#expressions

FreeMarker check the class name of an object

is there a way to get the class name of an object in a freemarker template ?
For instance:
<#if component.javaType.class.name.equals("test") >
"something...."
</#else>
"something else ...."
</#if>
Thanks
There's no feature built in for that, but depending on the configuration settings and on the type of the object, this may works:
<#if component.class.name == 'com.example.Something'>
That works because component.foo simply means comonent.getFoo() in Java, so the above just means component.getClass().getName(). This, however doesn't work if the JavaBean properties of component aren't exposed, which (assuming the usual FreeMarker configuration) is the case for String-s, Number-s, Map-s, List-s and some more "standard" classes. If component can be a such object, but the comparison should be false for them anyway, you can write (component.class.name)!'unknown' == 'com.example.Something'.

FreeMarker Java 8 Optional value support

Does FreeMarker support Optional value in Java 8?
e.g. I have String id, and its getter method is like:
public Optional<String> getId() {
return Optional.ofNullable(Id);
}
How am I going to reference it in the .ftl file. It seems that {data.id} can not find the correct Optional value. But gives me Optional[1334586]
Well, Freemarker is not supposed to be aware of Optional or it is better to say that its dynamically typed so it works for any object.
Since you calling ${data.id} it's just calls toString on Optional which is totally expected behavior.
If you want to handle null values in your template and for that you want to use Optional, you may choose to set a default value if null, so Optional usage won't be needed:
Synopsis: unsafe_expr!default_expr or unsafe_expr! or (unsafe_expr)!default_expr or (unsafe_expr)!
Example: ${data.id!"No id."}
Or check if it's exists:
<#if data?? && data.id??>
Id found
<#else>
Id not found
</#if>
For more info check out the Freemarker docs. Specifically parts: Handling missing values and Missing value test operator.
If you just want to get the value from Optional in your template:
${data.id.orElse('')}
or
${data.id.get()!''}

Ternary operator in Spring

My question is similar to this question. Since that question is quite old so thought of posting new question.
I am also writing my expression in following
<property name="to" value="#{ systemProperties['BR']} == '01' ?
${PROPERTY_VALUE_1_FROM_BUNDLE} :
${PROPERTY_VALUE_2_FROM_BUNDLE}" />
When I fetch the value of "to" variable from my bean. Its giving me something like below
01='01'? value1 : value2
Its not parsing my expression in XML itself.
Am I doing anything wrong here?
You are terminating the SpEL too early; it should be...
<property name="to" value="#{ systemProperties['BR'] == '01' ?
'${PROPERTY_VALUE_1_FROM_BUNDLE}' :
'${PROPERTY_VALUE_2_FROM_BUNDLE}' }" />
Note that you also need single quotes around the placeholders so the resolved values are treated as literals.
I have resolved it using below code
ExpressionParser parser = new SpelExpressionParser();
String toMail = parser.parseExpression(to).getValue(String.class);
Had to make little here and there in XML but its responding as I wanted it to. Now I am getting either value in my "to" variable.

Spring config string format

A stupid question on formatting but not able to figure out the correct negate parameter. I've the following string value which needs to be passed as a constructor arg through spring.
private final static String STRING_PATTERN = "\\<.*?>";
In spring config,
<bean class="com.test.TestBean">
<constructor-arg value="\\<.*?>" />
</bean>
As you can see, its not in the correct format. Can anyone please provide a clue ?
Thanks
Since Spring config is an XML file
there is no need to replace \ with \\ as in Java string literals
you need to replace < and > with < and >
So, you get
<constructor-arg value="\<.*?>" />

Resources