Spring SpEL-用于创建字符串映射和自定义对象的表达式语言



我使用Spring Boot示例从属性文件中读取以下内容。

sub.region.data={
AF: {'subRegionCd' : '34', 'subRegionName' : 'Southern Asia', 'subRegionDesc': '', 'status' : 'A'} 
}

我用过下面的,但它不起作用

@Value("#{${sub.region.data}}")
private Map<String, SubRegion> subRegionsMap; 

SubRegion.java

public class SubRegion {
private String subRegionCd;
private String subRegionName;
private String subRegionDesc;
private String subRegionStatus;
}

我得到低于错误

Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.util.Collections$UnmodifiableMap' to required type 'java.util.Map'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.util.Collections$UnmodifiableMap' to required type 'com.xxxxxx.model.SubRegion': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:76) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1195) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
... 54 common frames omitted
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.util.Collections$UnmodifiableMap' to required type 'com.xxxxxx.model.SubRegion': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:262) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.TypeConverterDelegate.convertToTypedMap(TypeConverterDelegate.java:608) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:182) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:73) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
... 57 common frames omitted

看起来您在'subRegionDesc',之后犯了一个错误,我认为您的意思是使用冒号,而不是逗号

对于spring-boot,我建议您使用ConfigurationProperties,而不是@Value

例如,在这种情况下,您必须:

  1. @EnableConfigurationProperties(SubRegionConfig.class)放到您的一个spring配置类中。

  2. 创建配置类:

    @ConfigurationProperties(prefix = "sub.region")
    public static class SubRegionConfig {
    private Map<String, SubRegion> data;
    //getters and setters
    } 
    
  3. 使用.yml而不是.properties,就像这样:

    sub:
    region:
    data:
    AF:
    subRegionCd: '34'
    subRegionName: 'Southern Asia'
    subRegionDesc: ''
    subRegionStatus: 'A'
    
  4. 之后,您可以从SubRegionConfing中获得您想要的所有属性

    @Autowired
    private SubRegionConfig subRegionConfig;
    

ConfigurationsProperties更复杂,但在大多数情况下更灵活,更适合使用。

#{}操作符将数据发送到spEL解析器,这意味着它将尝试根据Spring Docs中的spEL语法将数据转换为已知类型。

发生的情况是编译器无法将任何数据转换为SubRegion对象:

无法转换类型为"java.util.Collections$UnmodifiebleMap"的值到所需类型"com.xxxxxx.model.SubRegion":没有匹配的编辑器或找到的转换策略

一个简单的解决方法是嵌套两个Map对象,以便在检索值后填充SubRegion对象。

yourMap={'key1':{'nestedMapKey1:value', 'nestedMapKey2:value2'}}

在你的.properties文件和你的代码中:

sub.region.data={'AF':{'subRegionCd':'34', 'subRegionName':'Southern Asia', 'subRegionDesc':'', 'status':'A'}}

然后,在你的代码中:

@Value("#{${sub.region.data}}")
private Map<String, Map<String, String>> subRegionsMap;
// (...) handling the SubRegion

我的System.out.println(subRegionMap.get("AF"(输出:

{subRegionCd=34, subRegionName=Southern Asia, subRegionDesc=, status=A}

最新更新