【问题标题】:Spring boot configuration problem with YAML filesYAML 文件的 Spring Boot 配置问题
【发布时间】:2026-02-24 22:10:02
【问题描述】:

我有以下 yaml 文件

    proj:
     sms:
      gateway:
        username: d
        password: erer
        signature: e
        url: http://link.somelink.com
      actionKeyMap:
       OTP_GENERATOR: Value1
       CREATE_USER: Value2

我正在尝试将 actionKeyMap/gateway 属性绑定到 Java 映射中,但它不起作用。

我试过下面的代码

@Component
@ConfigurationProperties(prefix="proj.sms")
public class MessageResolver {

    //@Value("${proj.sms.actionKeyMap}")
    private Map<String, String> actionKeyMap;

ConfigurationProperties 或 Value 注释不起作用。

【问题讨论】:

  • 你设置了@EnableConfigurationProperties(MessageResolver.class) 吗?
  • 我尝试了与您发布的相同的代码,它无需任何更改即可工作,除了我对 yml 做了一些格式化

标签: spring spring-boot yaml snakeyaml


【解决方案1】:

如 cmets 中所述添加代码

Application.yml

proj:
  sms:
    gateway:
        username: d
        password: erer
        signature: e
        url: http://link.somelink.com
    actionKeyMap:
      OTP_GENERATOR: Value1
      CREATE_USER: Value2

Spring boot Application.java

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
//@EnableConfigurationProperties
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);

    }
}

MessageResolver.java

package hello;

import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix="proj.sms")
public class MessageResolver {

    //@Value("${proj.sms.actionKeyMap}")
    private Map<String, String> actionKeyMap;

    @Value("${proj.sms.actionKeyMap.OTP_GENERATOR}")
    private String test;

    public String getTest() {
        return test;
    }

    public void setTest(String test) {
        this.test = test;
    }

    public Map<String, String> getActionKeyMap() {
        return actionKeyMap;
    }

    public void setActionKeyMap(Map<String, String> actionKeyMap) {
        this.actionKeyMap = actionKeyMap;
    }

}

GreetingController.java

package hello;

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @Autowired
    MessageResolver messageResolver;

    @RequestMapping("/greeting")
    public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {

        System.out.println(messageResolver.getTest());
        System.out.println(messageResolver.getActionKeyMap());
        return new Greeting(counter.incrementAndGet(),
                            String.format(template, name));
    }
}

Greeting.java(以防您尝试构建完整的项目)

package hello;

public class Greeting {

    private final long id;
    private final String content;

    public Greeting(long id, String content) {
        this.id = id;
        this.content = content;
    }

    public long getId() {
        return id;
    }

    public String getContent() {
        return content;
    }
}

网址 http://localhost:8080/greeting

控制台输出来自 GreetingController(第 22 和 23 行)

Value1
{OTP_GENERATOR=Value1, CREATE_USER=Value2}

【讨论】:

  • 谢伊莱什,我感激不尽。我错过了属性的获取/设置。为什么@Value 注释不需要get/set 而@ConfigurationProperties 需要?另外,@SpringBootApplication 可以扫描@ConfigurationProperties?呸!谢谢,伙计
  • 此评论仅供参考 - docs.spring.io/spring-boot/docs/2.1.8.RELEASE/reference/html/… 弄清楚@ConfigurationProperties@Value 之间的区别
【解决方案2】:

您只需声明GatewayActionKeyMap 类以匹配ymlproperty。或者您可以在此处阅读 Spring Boot 参考,link

@Component
@ConfigurationProperties(prefix="proj.sms")
public class MessageResolver {
    private Gateway gateway;
    private ActionKeyMap actionKeyMap;
    //getter/setter
}

``

public class Gateway {
    private String username;
    private String password;
    private String signature;
    private String url;
    //getter/setter
}

``

public class ActionKeyMap {
    private String OTP_GENERATOR;
    private String CREATE_USER;
    //getter/setter
}

【讨论】:

  • 好的。我会尝试再次解释。我在这里想要实现的是一个简单的键值对映射,它可能会改变。因此,拥有一个特定于每个键的属性无论如何都是一个糟糕的设计。另外,这是一个经典的类爆炸问题,我认为我们应该避免。
  • 当然可以绑定Map属性,参考这里docs.spring.io/spring-boot/docs/2.1.8.RELEASE/reference/html/…
【解决方案3】:

尝试:(冒号)而不是.(点)

@Component
@ConfigurationProperties(prefix="proj:sms")
public class MessageResolver {

    @Value("${proj:sms:actionKeyMap}")
    private Map<String, String> actionKeyMap;

【讨论】:

  • 为什么冒号会起作用而不是点?你能给我一个链接吗?
  • 你能分享我一个github链接吗?谢谢
【解决方案4】:

您可以通过此链接获取有关如何解决您的问题的信息:How to inject a Map using the @Value Spring Annotation?

它看起来像:

actionKeyMap: '{
  OTP_GENERATOR: "value1",
  CREATE_USER: "value2"
}'

【讨论】:

  • 所以当我尝试这个时,我得到以下异常 - 原因:java.lang.IllegalStateException:无法将类型“java.lang.String”的值转换为所需类型“java.util.Map” : 未找到匹配的编辑器或转换策略