smp7d
smp7d

Reputation: 5032

Spring nullable String Bean

I have a filtered configuration like so (using Maven for filtering):

<bean class="com.whatever.SomeClass">
    <property name="someString" value="${filter.prop.value}"/>
</bean>

Sometimes that string property needs to be null (for reasons I wont go into here), so I need a way to specify the property as null. Clearly if I filter with the property file value "null", the bean property will be the String "null" instead of actually null.

I am aware that I can create something like a NullableStringFactoryBean which can look for the string "null" and handle it appropriately.

My question is: Does Spring provide a mechanism to do this already or is there some better way I can go about achieving this?

Upvotes: 0

Views: 940

Answers (3)

user159088
user159088

Reputation:

Have a look at the setNullValue method from the PropertyPlaceholderConfigurer class and see if it helps given your situation.

Set a value that should be treated as null when resolved as a placeholder value: e.g. "" (empty String) or "null".

EDIT: Since you are using Maven filtering and don't want to have two mechanisms (one done by Maven on the process-resources phase and later, at runtime, one done by Spring) I see only three options:

1) Use a "smart" setter as @Tomasz Nurkiewicz specified in his answer. This might have side effects though as you also mentioned and might become "to smart for one's own good".

2) Inject the value of the property by using a FactoryBean<String> as you demonstrated in the answer you added to the question (with Spring's "p-namespace" being a nice way of limiting the amount of XML you have to write to accomplish this).

3) (crazy idea) replace the entire property injection in the XML. That is, instead of having this:

<bean class="com.whatever.SomeClass">
   <property name="someString" value="${filter.prop.value}"/>
</bean>

Have this:

<bean class="com.whatever.SomeClass">
   ${filter.prop.value}
</bean>

Now, filter.prop.value instead of null or someValidValue can become some white space and <property name="someString" value="someValidValue"/>, respectively.

This has the disadvantage that your IDE will complain about an invalid XML (since <bean> tag does not allow character children, only elements). But if you can live with that....

I would personally go for number 2.

Upvotes: 2

smp7d
smp7d

Reputation: 5032

Well, in case anyone was wondering how this is done with a FactoryBean...

public class NullLiteralResolvingStringFactoryBean implements
        FactoryBean<String> {
    private String value;

    @Override
    public String getObject() throws Exception {
        if (value == null || value.equals("null")) {
            return null;
        }
        return value;
    }

    @Override
    public Class<?> getObjectType() {
        return String.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    public void setValue(String value) {
        this.value = value;
    }

}

Config:

<bean id="someString" class="com.whatever.NullLiteralResolvingStringFactoryBean"
        p:value="${filter.someString}" />

Upvotes: 0

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340708

What about:

public void setSomeString(String value) {
  if(value == null || value.equals("") || value.equals("null")) {
    this.value = null;
  } else {
    this.value = value;
  }
}

Upvotes: 0

Related Questions