在Spring YAML配置文件中,我需要有一个参数
csv:
file:
pattern: /some/path/${app-name}.csv
其中${app-name}
在运行时由Java代码动态替换,我不希望Spring在启动时替换它。
要实现这一点,我需要逃避$
角色,因此Spring不会将其解释为SpEL。
以下答案在YAML中不起作用:
\$
How to escape EL dollar signs?#{'$'}
Escape property reference in Spring property file我试过所有的组合,比如
pattern: /some/path/\${app-name}.csv
pattern: "/some/path/\${app-name}.csv"
pattern: /some/path/#{'$'}{app-name}.csv
pattern: "/some/path/#{'$'}{app-name}.csv"
并且没有一个产生包含请求字符串的变量,带有美元符号但没有转义字符。
请注意它是YAML配置。在YAML文件中,#
是行注释字符,忽略此字符的所有内容。如果我使用\#
,那么\
将被传递给字符串。
Spring目前不提供属性占位符的转义机制,有一个open issue。在评论中,提到了这种解决方法(我不确定它是否适用于YAML):
csv:
file:
pattern: /some/path/#{'$'}{app-name}.csv
请注意,在空格之后或行的开头使用时,YAML中的#
会开始注释。
答案实际上取决于您在代码中注入值的确切方式。由于您尚未提供,我将列出各种工作技巧。
@Value
注释来注入您的属性。因为,unlike @ConfigurationProperties
, @Value
does SpEL evaluation,你必须逃避你的价值。application.yml:
csv:
file:
pattern: /some/path/#{'$'}{app-name}.csv
test controller.Java:
@RestController
public class TestController {
@Value("${csv.file.pattern}") private String pattern;
@GetMapping("pattern") public ResponseEntity<String> getPattern() {
return ResponseEntity.ok(pattern);
}
}
对/pattern
的GET会产生输出/some/path/#{app-name}.csv
,就像你需要的那样
@ConfigurationProperties
,这里它实际上取决于您如何构造配置对象。但是,一般情况下,@ConfigurationProperties
不需要转义,因为默认情况下它们不支持SpEL。但是,以下是有效的,因此如果您的设置不同,请对其进行修改:application.yml:
csv:
file:
pattern: /some/path/#{app-name}.csv
config.Java:
@ConfigurationProperties(prefix = "csv.file")
public class Config {
private String pattern;
public String getPattern() { return pattern; }
public void setPattern(String pattern) { this.pattern = pattern; }
}
test controller.Java:
@RestController
public class TestController {
@Autowired private Config config;
@GetMapping("pattern") public ResponseEntity<String> getPattern() {
return ResponseEntity.ok(config.getPattern());
}
}
同样,对/pattern
的GET将导致输出/some/path/#{app-name}.csv
您最有可能的是Config.java中的一些不同结构(可能会发布相关代码?),这可能导致属性无法正确处理。