-->

@Value annotation type casting to Integer from Str

2019-03-17 03:24发布

问题:

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.

回答1:

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}


回答2:

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.parseInt('${api.orders.pingFrequency}')}")
private Integer pingFrequency;


回答3:

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}" />



回答4:

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" />


回答5:

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



回答6:

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();
}


回答7:

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.



回答8:

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.



回答9:

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"/>