SnakeYAML 示例
SnakeYAML by example
我正在尝试使用 SnakeYAML 读取和解析 YAML 文件,并将其转换为我的 Java 应用程序的配置 POJO:
// Groovy pseudo-code
class MyAppConfig {
List<Widget> widgets
String uuid
boolean isActive
// Ex: MyAppConfig cfg = new MyAppConfig('/opt/myapp/config.yaml')
MyAppConfig(String configFileUri) {
this(loadMap(configFileUri))
}
private static HashMap<String,HashMap<String,String>> loadConfig(String configFileUri) {
Yaml yaml = new Yaml();
HashMap<String,HashMap<String,String>> values
try {
File configFile = Paths.get(ClassLoader.getSystemResource(configUri).toURI()).toFile();
values = (HashMap<String,HashMap<String,String>>)yaml.load(new FileInputStream(configFile));
} catch(FileNotFoundException | URISyntaxException ex) {
throw new MyAppException(ex.getMessage(), ex);
}
values
}
MyAppConfig(HashMap<String,HashMap<String,String>> yamlMap) {
super()
// Here I want to extract keys from 'yamlMap' and use their values
// to populate MyAppConfig's properties (widgets, uuid, isActive, etc.).
}
}
示例 YAML:
widgets:
- widget1
name: blah
age: 3000
isSilly: true
- widget2
name: blah meh
age: 13939
isSilly: false
uuid: 1938484
isActive: false
因为 出现 SnakeYAML 只给我一个 HashMap<String,<HashMap<String,String>>
来表示我的配置数据,似乎我们只能有 2 个 SnakeYAML 支持的嵌套映射属性(外部地图和内部地图类型 <String,String>
)...
- 但是,如果
widgets
包含一个 list/sequence(比如,fizzes
),其中包含一个列表,比方说,buzzes
,又包含另一个列表,等等?这仅仅是 SnakeYAML 的限制还是我错误地使用了 API?
- 要从此地图中提取值,我需要迭代它的 keys/values 并且(似乎)需要应用我自己的自定义验证。 SnakeYAML 是否提供任何 API 来执行此提取 + 验证?例如,与其手动编写我自己的代码来检查
uuid
是否是地图中定义的 属性,如果我能做类似 yaml.extract('uuid')
的事情就太好了,等等. 然后同上 uuid
(以及任何其他 属性)的后续验证。
- YAML本身包含了很多强大的概念,比如锚点和引用。 SnakeYAML 是否处理这些概念?如果最终用户在配置文件中使用它们怎么办 - 我应该如何 detect/validate/enforce 它们?!? SnakeYAML 是否为此提供 API?
你的意思是这样的吗:
@Grab('org.yaml:snakeyaml:1.17')
import org.yaml.snakeyaml.*
import org.yaml.snakeyaml.constructor.*
import groovy.transform.*
String exampleYaml = '''widgets:
| - name: blah
| age: 3000
| silly: true
| - name: blah meh
| age: 13939
| silly: false
|uuid: 1938484
|isActive: false'''.stripMargin()
@ToString(includeNames=true)
class Widget {
String name
Integer age
boolean silly
}
@ToString(includeNames=true)
class MyConfig {
List<Widget> widgets
String uuid
boolean isActive
static MyConfig fromYaml(yaml) {
Constructor c = new Constructor(MyConfig)
TypeDescription t = new TypeDescription(MyConfig)
t.putListPropertyType('widgts', Widget)
c.addTypeDescription(t);
new Yaml(c).load(yaml)
}
}
println MyConfig.fromYaml(exampleYaml)
显然,这是 Groovy 控制台中 运行 的脚本,您不需要 @Grab
行,因为您的类路径中可能已经有该库;- )
我正在尝试使用 SnakeYAML 读取和解析 YAML 文件,并将其转换为我的 Java 应用程序的配置 POJO:
// Groovy pseudo-code
class MyAppConfig {
List<Widget> widgets
String uuid
boolean isActive
// Ex: MyAppConfig cfg = new MyAppConfig('/opt/myapp/config.yaml')
MyAppConfig(String configFileUri) {
this(loadMap(configFileUri))
}
private static HashMap<String,HashMap<String,String>> loadConfig(String configFileUri) {
Yaml yaml = new Yaml();
HashMap<String,HashMap<String,String>> values
try {
File configFile = Paths.get(ClassLoader.getSystemResource(configUri).toURI()).toFile();
values = (HashMap<String,HashMap<String,String>>)yaml.load(new FileInputStream(configFile));
} catch(FileNotFoundException | URISyntaxException ex) {
throw new MyAppException(ex.getMessage(), ex);
}
values
}
MyAppConfig(HashMap<String,HashMap<String,String>> yamlMap) {
super()
// Here I want to extract keys from 'yamlMap' and use their values
// to populate MyAppConfig's properties (widgets, uuid, isActive, etc.).
}
}
示例 YAML:
widgets:
- widget1
name: blah
age: 3000
isSilly: true
- widget2
name: blah meh
age: 13939
isSilly: false
uuid: 1938484
isActive: false
因为 出现 SnakeYAML 只给我一个 HashMap<String,<HashMap<String,String>>
来表示我的配置数据,似乎我们只能有 2 个 SnakeYAML 支持的嵌套映射属性(外部地图和内部地图类型 <String,String>
)...
- 但是,如果
widgets
包含一个 list/sequence(比如,fizzes
),其中包含一个列表,比方说,buzzes
,又包含另一个列表,等等?这仅仅是 SnakeYAML 的限制还是我错误地使用了 API? - 要从此地图中提取值,我需要迭代它的 keys/values 并且(似乎)需要应用我自己的自定义验证。 SnakeYAML 是否提供任何 API 来执行此提取 + 验证?例如,与其手动编写我自己的代码来检查
uuid
是否是地图中定义的 属性,如果我能做类似yaml.extract('uuid')
的事情就太好了,等等. 然后同上uuid
(以及任何其他 属性)的后续验证。 - YAML本身包含了很多强大的概念,比如锚点和引用。 SnakeYAML 是否处理这些概念?如果最终用户在配置文件中使用它们怎么办 - 我应该如何 detect/validate/enforce 它们?!? SnakeYAML 是否为此提供 API?
你的意思是这样的吗:
@Grab('org.yaml:snakeyaml:1.17')
import org.yaml.snakeyaml.*
import org.yaml.snakeyaml.constructor.*
import groovy.transform.*
String exampleYaml = '''widgets:
| - name: blah
| age: 3000
| silly: true
| - name: blah meh
| age: 13939
| silly: false
|uuid: 1938484
|isActive: false'''.stripMargin()
@ToString(includeNames=true)
class Widget {
String name
Integer age
boolean silly
}
@ToString(includeNames=true)
class MyConfig {
List<Widget> widgets
String uuid
boolean isActive
static MyConfig fromYaml(yaml) {
Constructor c = new Constructor(MyConfig)
TypeDescription t = new TypeDescription(MyConfig)
t.putListPropertyType('widgts', Widget)
c.addTypeDescription(t);
new Yaml(c).load(yaml)
}
}
println MyConfig.fromYaml(exampleYaml)
显然,这是 Groovy 控制台中 运行 的脚本,您不需要 @Grab
行,因为您的类路径中可能已经有该库;- )