【问题标题】:How to parse a list of list of spring properties如何解析弹簧属性列表的列表
【发布时间】:2021-01-31 00:43:31
【问题描述】:

我有这个 Spring boot application.properties

list1=valueA,valueB
list2=valueC
list3=valueD,valueE

topics=list1,list2,list3

我要做的是在@KafkaListener 注释的topics 元素中使用主题属性值的值

使用表达式

@KafkaListener(topics={"#{'${topics}'.split(',')}"})

我得到list1,list2,list3 作为分隔字符串

如何在此列表中循环以获得valueA,valueB,valueC,valueD,valueE

编辑:我必须解析topics 属性,以便@KafkaListener 注册消费来自主题valueAvalueBvalueC 等的消息。

我读到可以这样调用方法:

@KafkaListener(topics="#parse(${topics})")

所以,我写了这个方法:

public String[] parse(String s) {
   ExpressionParser parser = new SpelExpressionParser();

   return Arrays.stream(s.split(",").map(key -> (String)(parser.parse(key).getValue())).toArray(String[]::new);
}

但是parse方法没有被调用

所以,我尝试直接在注释中这样做 这样:

@KafkaListener(topics="#{Arrays.stream('${topics}'.split(',')).map(key->${key}).toArray(String[]::new)}")

但这个解决方案也会给我错误。

编辑 2:

以这种方式修改方法被调用

@KafkaListener(topics="parse()")

@Bean
    public String[] parse(String s) {
       ...
    }

问题是如何在方法中获取“主题”道具

【问题讨论】:

  • 不清楚你的意思; topics 接受String[]
  • 好的。我正在尝试这样做:@KafkaListener(topics="#{parse($(topics))}")。方法 parse 返回Arrays.stream(s.split(",")).map(p -> "${p}").toArray(String[]::new);。我知道 ${p} 在 map 中没有意义,但是该方法没有被调用。
  • 还不清楚;编辑问题以准确显示您要执行的操作以及问题所在。
  • 我编辑了这个问题。我希望现在很清楚。

标签: spring-boot spring-kafka spring-el


【解决方案1】:

你不能像那样调用任意方法;你需要引用一个bean @someBean.parse(...);使用#parse 需要将静态方法注册为函数。

但是,这对我有用,而且更简单:

list1=valueA,valueB
list2=valueC
list3=valueD,valueE

topics=${list1},${list2},${list3}

@KafkaListener(id = "so64390079", topics = "#{'${topics}'.split(',')}")

编辑

如果您不能在 topics 中使用占位符,这可行...

@SpringBootApplication
public class So64390079Application {

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

    @KafkaListener(id = "so64390079", topics = "#{@parser.parse('${topics}')}")
    public void listen(String in) {
        System.out.println(in);
    }

}

@Component
class Parser implements EnvironmentAware {

    private Environment environmment;

    @Override
    public void setEnvironment(Environment environment) {
        this.environmment = environment;
    }

    public String[] parse(String[] topics) {
        StringBuilder sb = new StringBuilder();
        for (String topic : topics) {
            sb.append(this.environmment.getProperty(topic));
            sb.append(',');
        }
        return StringUtils.commaDelimitedListToStringArray(sb.toString().substring(0, sb.length() - 1));
    }

}

【讨论】:

  • 我想这样做,但要求主题属性必须是topics=list1,list2,list3 格式。
  • 似乎有效,但它被调用了两次,第二次给出了 StringIndexOutOfBoundException 因为主题参数为空。为什么会被调用两次?
  • 我不知道;它只在我的测试应用程序中调用一次;尝试设置断点以查看它是否提供任何线索。您始终可以添加代码来防止这种情况发生。 (if (sb.length() > 0)。
  • 在调试模式下检查,第一次得到正确的输出,但第二次得到错误。很奇怪。
猜你喜欢
  • 2018-08-31
  • 2012-06-08
  • 1970-01-01
  • 2017-07-11
  • 2010-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多