【问题标题】:@Value annotation type casting to Integer from String@Value 注释类型从 String 转换为 Integer
【发布时间】:2013-03-01 22:06:38
【问题描述】:

我正在尝试将值的输出转换为整数:

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

上面抛出错误

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

我也试过@Value("(java.lang.Integer)${api.orders.pingFrequency}")

Google 似乎没有在这个主题上发表太多意见。我希望始终处理一个整数,而不是在使用它的任何地方解析这个值。

解决方法

我意识到一种解决方法可能是使用 setter 方法为我运行转换,但如果 Spring 可以做到,我宁愿学习一些有关 Spring 的知识。

【问题讨论】:

  • 第一次尝试还是第二次例外?
  • @SotiriosDelimanolis 第一个
  • 如果您遇到过这样的问题,最明显的原因是您忘记定义正确的 PropertySource。你需要: @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); }
  • 也可能是属性文件编码不当造成的(java需要ISO 8859-1)
  • 属性占位符末尾缺少花括号对我造成了此错误:/

标签: java spring casting annotations property-placeholder


【解决方案1】:

假设您的类路径中有一个包含

的属性文件
api.orders.pingFrequency=4

我在@Controller里面试过

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

我的 servlet 上下文包含:

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

效果很好。

所以要么你的属性不是整数类型,要么你没有正确配置属性占位符,要么你使用了错误的属性键。

我尝试使用无效的属性值 4123; 运行。我得到的例外是

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

这让我觉得你的财产的价值是

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

【讨论】:

    【解决方案2】:

    我在网上寻找答案,我发现了以下内容

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

    所以你可以试试这个

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

    【讨论】:

    • 这给了我 SpelEvaluationException。你确定它有效吗?
    • 我也收到了 SpelEvaluationException
    • 使用 'new Integer' 而不是 'new Integer.parseInt' 对我有用。
    • 我收到 java.lang.NumberFormatException: For input string: "${redis.server.port}&quot
    • 确保你没有遗漏 $ @Value("${api.orders.pingFrequency}") 应该可以正常工作
    【解决方案3】:

    如果您想将 property 从属性文件转换为 integer,我找到了 2 个解决方案:

    给定场景:customer.properties 包含 customer.id = 100 作为字段,您希望在 spring 配置文件中以 integer 的形式访问它>.属性 customerId 在 Bean Customer

    中声明为 int 类型

    解决方案 1:

    &lt;property name="customerId" value="#{T(java.lang.Integer).parseInt('${customer.id}')}" /&gt;

    在上述行中,属性文件中的 string 值被转换为 int 类型。

    解决方案 2:使用其他扩展名代替 propeties。例如,如果您的属性文件名是 customer.properties 然后将其设为 customer.details 并在配置文件中使用以下代码

    &lt;property name="customerId"  	value="${customer.id}" /&gt;

    【讨论】:

      【解决方案4】:

      我也有同样的情况。这是由于 Spring 上下文中没有 PropertySourcesPlaceholderConfigurer 引起的,它根据类中的 @Value 注释解析值。

      包含属性占位符解决问题,整数不需要使用Spring表达式(使用ignore-resource-not-found="true",属性文件不必存在):

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

      【讨论】:

        【解决方案5】:

        如果您使用的是@Configuation,则在静态 bean 下进行实例化。如果不是静态的 @Configutation 很早就被实例化,并且负责解析 @Value、@Autowired 等注释的 BeanPostProcessors 无法对其进行操作。参考here

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

        【讨论】:

        • 补充上述内容,鉴于属性配置器@Bean 只会出现在一个配置类中,从代码库中删除任何配置类时应小心,这可能会无意中删除此 bean。
        【解决方案6】:

        我有同样的问题,我用这个解决了。参考这个Spring MVC: @Value annotation to get int value defined in *.properties file

        @Value(#{propertyfileId.propertyName})
        

        作品

        【讨论】:

        • 对不起,它不起作用。 #{...} 给我编译错误。相反,您可以使用 int 而不是 Integer...
        【解决方案7】:

        当您有 2 个具有相同文件名的资源时也会出现此问题;在类路径中配置的 2 个不同的 jar 或目录路径中说“configurations.properties”。例如:

        您的流程或 Web 应用程序(jar、war 或 ear)中有您的“configurations.properties”。但是另一个依赖项(jar)在同一路径中具有相同的文件“configurations.properties”。然后我想 Spring 不知道(@_@?)从哪里获取属性,只是发送在 @Value 注释中声明的属性名称。

        【讨论】:

          【解决方案8】:

          在我的例子中,问题是我的 POST 请求被发送到与 GET 相同的 url(使用“?..=..”获取参数)并且参数与表单参数具有相同的名称。可能 Spring 正在将它们合并到一个数组中并且解析抛出错误。

          【讨论】:

            【解决方案9】:

            使用@Value 时,应在Class 上添加@PropertySource 注解,或在spring 的xml 文件中指定properties holder。 例如。

            @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
            

            这行得通!

            当然,你可以使用占位符xml配置代替注解。 spring.xml

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

            【讨论】:

              【解决方案10】:

              由于使用 @Value("new Long("myconfig")") 进行强制转换可能会在启动抛出错误,如果 找不到配置,或者如果不是相同的预期数字格式

              我们使用了以下方法,并且通过故障安全检查按预期工作。

              @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;
                  }
              }
                 
              

              【讨论】:

                猜你喜欢
                • 2019-05-05
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-12-06
                • 1970-01-01
                • 2014-02-22
                相关资源
                最近更新 更多