Ben
Ben

Reputation: 62444

@Value annotation type casting to Integer from String

I'm trying to cast the output of a value to an integer:

@Value("${api.orders.pingFrequency}")
private Integer pingFrequency;

The above throws the error

org.springframework.beans.TypeMismatchException: 
    Failed to convert value of type 'java.lang.String' to required type 'java.lang.Integer'; 
nested exception is java.lang.NumberFormatException: 
    For input string: "(java.lang.Integer)${api.orders.pingFrequency}"

I've also tried @Value("(java.lang.Integer)${api.orders.pingFrequency}")

Google doesn't appear to say much on the subject. I'd like to always be dealing with an integer instead of having to parse this value everywhere it's used.

Workaround

I realize a workaround may be to use a setter method to run the conversion for me, but if Spring can do it I'd rather learn something about Spring.

Upvotes: 89

Views: 197636

Answers (11)

Rajeev Ranjan
Rajeev Ranjan

Reputation: 279

Instead of primitives datatype, Use Wrapper Integer/Double/Long class in java to get numeric value

@Value("${restaurant-top-food}")    
private Integer topBestFood;

Upvotes: 0

Mukundhan
Mukundhan

Reputation: 3477

Since using the @Value("new Long("myconfig")") with cast could throw error on startup if the config is not found or if not in the same expected number format

We used the following approach and is working as expected with fail safe check.

@Configuration()
public class MyConfiguration {

   Long DEFAULT_MAX_IDLE_TIMEOUT = 5l;

   @Value("db.timeoutInString")
   private String timeout;

   public Long getTimout() {
        final Long timoutVal = StringUtil.parseLong(timeout);
        if (null == timoutVal) {
            return DEFAULT_MAX_IDLE_TIMEOUT;
        }
        return timoutVal;
    }
}
   

Upvotes: 0

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280132

Assuming you have a properties file on your classpath that contains

api.orders.pingFrequency=4

I tried inside a @Controller

@Controller
public class MyController {     
    @Value("${api.orders.pingFrequency}")
    private Integer pingFrequency;
    ...
}

With my servlet context containing :

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

It worked perfectly.

So either your property is not an integer type, you don't have the property placeholder configured correctly, or you are using the wrong property key.

I tried running with an invalid property value, 4123;. The exception I got is

java.lang.NumberFormatException: For input string: "4123;"

which makes me think the value of your property is

api.orders.pingFrequency=(java.lang.Integer)${api.orders.pingFrequency}

Upvotes: 69

Piero Divasto
Piero Divasto

Reputation: 1135

I was looking for the answer on internet and I found the following

@Value("#{new java.text.SimpleDateFormat('${aDateFormat}').parse('${aDateStr}')}")
Date myDate;

So in your case you could try with this

@Value("#{new Integer('${api.orders.pingFrequency}')}")
private Integer pingFrequency;

Upvotes: 42

warhead
warhead

Reputation: 11

when use @Value, you should add @PropertySource annotation on Class, or specify properties holder in spring's xml file. eg.

@Component
@PropertySource("classpath:config.properties")
public class BusinessClass{
   @Value("${user.name}")
   private String name;
   @Value("${user.age}")
   private int age;
   @Value("${user.registed:false}")
   private boolean registed;
}

config.properties

user.name=test
user.age=20
user.registed=true

this works!

Of course, you can use placeholder xml configuration instead of annotation. spring.xml

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

Upvotes: 1

V N
V N

Reputation: 353

If you are using @Configuation then instantiate below static bean. If not static @Configutation is instantiated very early and and the BeanPostProcessors responsible for resolving annotations like @Value, @Autowired etc, cannot act on it. Refer here

@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigurer() {
   return new PropertySourcesPlaceholderConfigurer();
}

Upvotes: 6

Krystian
Krystian

Reputation: 2290

In my case, the problem was that my POST request was sent to the same url as GET (with get parameters using "?..=..") and that parameters had the same name as form parameters. Probably Spring is merging them into an array and parsing was throwing error.

Upvotes: 0

Gabriel Villacis
Gabriel Villacis

Reputation: 321

This problem also occurs when you have 2 resources with the same file name; say "configurations.properties" within 2 different jar or directory path configured within the classpath. For example:

You have your "configurations.properties" in your process or web application (jar, war or ear). But another dependency (jar) have the same file "configurations.properties" in the same path. Then I suppose that Spring have no idea (@_@?) where to get the property and just sends the property name declared within the @Value annotation.

Upvotes: 0

Saurabh
Saurabh

Reputation: 7833

I had the same issue I solved using this. Refer this Spring MVC: @Value annotation to get int value defined in *.properties file

@Value(#{propertyfileId.propertyName})

works

Upvotes: 1

this
this

Reputation: 141

I had the exact same situation. It was caused by not having a PropertySourcesPlaceholderConfigurer in the Spring context, which resolves values against the @Value annotation inside of classes.

Include a property placeholder to solve the problem, no need to use Spring expressions for integers (the property file does not have to exist if you use ignore-resource-not-found="true"):

<context:property-placeholder location="/path/to/my/app.properties"
    ignore-resource-not-found="true" />

Upvotes: 9

aJaY
aJaY

Reputation: 71

If you want to convert a property to an integer from properties file there are 2 solutions which I found:

Given scenario: customer.properties contains customer.id = 100 as a field and you want to access it in spring configuration file as integer.The property customerId is declared as type int in the Bean Customer

Solution 1:

<property name="customerId" value="#{T(java.lang.Integer).parseInt('${customer.id}')}" />

In the above line, the string value from properties file is converted to int type.

solution 2: Use some other extension inplace of propeties.For Ex.- If your properties file name is customer.properties then make it customer.details and in the configuration file use the below code

<property name="customerId"  	value="${customer.id}" />

Upvotes: 7

Related Questions