如何读取 java 中的 YAML 文件?
How to read from YAML file in java?
我有这样的 YAML 文件..
Product:
ProductA:
Suite:
SuiteName_A:
Environment_1: ["A","B","C"]
Environment_2: ["X","Y","Z"]
SuiteName_B:
Environment_1: ["E","F","G"]
Environment_2: ["K","L","M"]
ProductB:
Suite:
SuiteName_K:
Environment_1: ["A1","B2","C3"]
Environment_2: ["X1","Y1","Z1"]
已编辑----
我在阅读一些阅读文章时创建了一些 classes,这里是我想出的..
环境Class
package Configuration;
import java.util.ArrayList;
public class Environment {
private ArrayList<String> Environment_1;
private ArrayList<String> Environment_2;
public ArrayList<String> getEnvironment_1() {
return Environment_1;
}
public void setEnvironment_1(ArrayList<String> Environment_1) {
this.Environment_1 = Environment_1;
}
public ArrayList<String> getEnvironment_2() {
return Environment_2;
}
public void setEnvironment_2(ArrayList<String> Environment_2) {
this.Environment_1 = Environment_2;
}
}
套装名称Class
package Configuration;
import java.util.HashMap;
public class SuiteNames {
private HashMap<String,Environment> Suite;
public HashMap<String, Environment> getSuite() {
return Suite;
}
public void setSuite(HashMap<String, Environment> suite) {
Suite = suite;
}
}
产品Class
package Configuration;
import java.util.HashMap;
public class Product {
private HashMap<String,SuiteNames> Product;
public HashMap<String, SuiteNames> getProduct() {
return Product;
}
public void setProduct(HashMap<String, SuiteNames> product) {
this.Product = product;
}
}
主要Class
package Configuration;
import org.yaml.snakeyaml.Yaml;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
public class DbClass {
public static void main(String[] args) throws FileNotFoundException {
Yaml yaml = new Yaml();
InputStream inputStream = new FileInputStream("path");
System.out.println(inputStream);
Product product = yaml.loadAs(inputStream,Product.class);
System.out.println(product.getProduct());
}
}
这会产生以下错误:
Exception in thread "main" Cannot create property=Product for JavaBean=Configuration.Product@4c98385c
in 'reader', line 1, column 1:
Product:
^
Unable to find property 'Product' on class: Configuration.Product
in 'reader', line 2, column 3:
Check-in:
^
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:270)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.construct(Constructor.java:149)
at org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constructor.java:309)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructObjectNoCheck(BaseConstructor.java:216)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:205)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructDocument(BaseConstructor.java:164)
at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:148)
at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:525)
at org.yaml.snakeyaml.Yaml.loadAs(Yaml.java:519)
at Configuration.DbClass.main(DbClass.java:17)
Caused by: org.yaml.snakeyaml.error.YAMLException: Unable to find property 'Product' on class: Configuration.Product
at org.yaml.snakeyaml.introspector.PropertyUtils.getProperty(PropertyUtils.java:159)
at org.yaml.snakeyaml.introspector.PropertyUtils.getProperty(PropertyUtils.java:148)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.getProperty(Constructor.java:287)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:208)
... 9 more
我想获取环境名称列表并将其存储在列表中。我知道使用杰克逊 api。但我不知道如何将这些数据映射到 class。
我正在使用 servlet 并且在 servlet 内部我想要一个 java 方法来获取字符串列表。
YAML 列出了 Java 的推荐库:
SnakeYAML, YamlBeans and eo-yaml
其中使用最广泛的可能是 SnakeYAML。 Baeldung 在这里有一个非常容易理解的教程:https://www.baeldung.com/java-snake-yaml
[编辑以解决新代码并在 OP 编辑中输出]:
您使用的格式和命名约定也有一些问题。在你的 yaml 文件中,任何列表都需要 [brackets],实例变量需要是 camelCase,任何字符串都需要用引号括起来(包括 String HashMap 键):
products:
"ProductA":
suite:
"SuiteName_A":
environment_1: ["A","B","C"]
environment_2: ["X","Y","Z"]
"SuiteName_B":
environment_1: ["E","F","G"]
environment_2: ["K","L","M"]
"ProductB":
suite:
"SuiteName_K":
environment_1: ["A1","B2","C3"]
environment_2: ["X1","Y1","Z1"]
您应该尝试在您的 bean 命名约定中匹配它。此外,您的第二个 setter 需要设置 Environment_2 而不是 Environment_1。这是您的实体 类 的外观。
环境
package Configuration;
import java.util.ArrayList;
public class Environment {
private ArrayList<String> environment_1;
private ArrayList<String> environment_2;
public ArrayList<String> getEnvironment_1() {
return environment_1;
}
public void setEnvironment_1(ArrayList<String> environment_1) {
this.environment_1 = environment_1;
}
public ArrayList<String> getEnvironment_2() {
return environment_2;
}
public void setEnvironment_2(ArrayList<String> environment_2) {
this.environment_2 = environment_2;
}
}
套房名称
package Configuration;
import java.util.HashMap;
public class SuiteName {
private HashMap<String,Environment> suite;
public HashMap<String, Environment> getSuite() {
return suite;
}
public void setSuite(HashMap<String, Environment> suite) {
suite = suite;
}
}
package Configuration;
import java.util.HashMap;
public class Product {
private HashMap<String, SuiteName> products;
public HashMap<String, SuiteName> getProducts() {
return products;
}
public void setProducts(HashMap<String, SuiteName> products) {
this.products = products;
}
}
编辑:
在您的主要方法中,您可能希望使用 yaml.load(inputStream) 在 HashMap 中获取整个文件。根据您在评论中提出的问题,我添加了访问数据结构。
数据库类
package Configuration;
import org.yaml.snakeyaml.Yaml;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
public class DbClass {
public static void main(String[] args) throws FileNotFoundException {
Yaml yaml = new Yaml();
InputStream inputStream = new FileInputStream("path.yml");
System.out.println(inputStream);
HashMap yamlMap = yaml.load(inputStream);
for (Object o : yamlMap.entrySet()) {
System.out.println(o);
}
// Access HashMaps and ArrayList by key(s)
HashMap products = (HashMap) yamlMap.get("products");
HashMap product = (HashMap) products.get("ProductA");
HashMap suite = (HashMap) product.get("suite");
HashMap suiteName = (HashMap) suite.get("SuiteName_B");
ArrayList environment = (ArrayList) suiteName.get("environment_1");
System.out.println(environment);
}
}
这是无效的 YAML:
Environment_1: "A","B","C"
你需要做的
Environment_1: ["A","B","C"]
那么,setter的名字有误:
public ArrayList<String> getEnvironment_1() {
return Environment_1;
}
public void setINT(ArrayList<String> Environment_1) {
this.Environment_1 = Environment_1;
}
setter 必须命名为 setEnvironment_1
。这是因为 SnakeYAML 通过它们的 getters & setters.
访问私有字段
下一个问题是 YAML 中的名称以大写字母开头。 SnakeYAML 使用 JavaBeans API 来发现属性,这将产生 environment_1
作为 属性 名称,而不是 Environment_1
。您可以通过覆盖 属性 discovery:
来解决这个问题
final PropertyUtils uppercaseUtils = new PropertyUtils() {
@Override
public Property getProperty(Class<? extends Object> type, String name) throws IntrospectionException {
return super.getProperty(name.substring(0, 1). toLowerCase() + name. substring(1));
}
}
final Constructor c = new Constructor(Product.class);
c.setPropertyUtils(uppercaseUtils);
Yaml yaml = new Yaml(c);
我有这样的 YAML 文件..
Product:
ProductA:
Suite:
SuiteName_A:
Environment_1: ["A","B","C"]
Environment_2: ["X","Y","Z"]
SuiteName_B:
Environment_1: ["E","F","G"]
Environment_2: ["K","L","M"]
ProductB:
Suite:
SuiteName_K:
Environment_1: ["A1","B2","C3"]
Environment_2: ["X1","Y1","Z1"]
已编辑---- 我在阅读一些阅读文章时创建了一些 classes,这里是我想出的..
环境Class
package Configuration;
import java.util.ArrayList;
public class Environment {
private ArrayList<String> Environment_1;
private ArrayList<String> Environment_2;
public ArrayList<String> getEnvironment_1() {
return Environment_1;
}
public void setEnvironment_1(ArrayList<String> Environment_1) {
this.Environment_1 = Environment_1;
}
public ArrayList<String> getEnvironment_2() {
return Environment_2;
}
public void setEnvironment_2(ArrayList<String> Environment_2) {
this.Environment_1 = Environment_2;
}
}
套装名称Class
package Configuration;
import java.util.HashMap;
public class SuiteNames {
private HashMap<String,Environment> Suite;
public HashMap<String, Environment> getSuite() {
return Suite;
}
public void setSuite(HashMap<String, Environment> suite) {
Suite = suite;
}
}
产品Class
package Configuration;
import java.util.HashMap;
public class Product {
private HashMap<String,SuiteNames> Product;
public HashMap<String, SuiteNames> getProduct() {
return Product;
}
public void setProduct(HashMap<String, SuiteNames> product) {
this.Product = product;
}
}
主要Class
package Configuration;
import org.yaml.snakeyaml.Yaml;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
public class DbClass {
public static void main(String[] args) throws FileNotFoundException {
Yaml yaml = new Yaml();
InputStream inputStream = new FileInputStream("path");
System.out.println(inputStream);
Product product = yaml.loadAs(inputStream,Product.class);
System.out.println(product.getProduct());
}
}
这会产生以下错误:
Exception in thread "main" Cannot create property=Product for JavaBean=Configuration.Product@4c98385c
in 'reader', line 1, column 1:
Product:
^
Unable to find property 'Product' on class: Configuration.Product
in 'reader', line 2, column 3:
Check-in:
^
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:270)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.construct(Constructor.java:149)
at org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constructor.java:309)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructObjectNoCheck(BaseConstructor.java:216)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:205)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructDocument(BaseConstructor.java:164)
at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:148)
at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:525)
at org.yaml.snakeyaml.Yaml.loadAs(Yaml.java:519)
at Configuration.DbClass.main(DbClass.java:17)
Caused by: org.yaml.snakeyaml.error.YAMLException: Unable to find property 'Product' on class: Configuration.Product
at org.yaml.snakeyaml.introspector.PropertyUtils.getProperty(PropertyUtils.java:159)
at org.yaml.snakeyaml.introspector.PropertyUtils.getProperty(PropertyUtils.java:148)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.getProperty(Constructor.java:287)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:208)
... 9 more
我想获取环境名称列表并将其存储在列表中。我知道使用杰克逊 api。但我不知道如何将这些数据映射到 class。 我正在使用 servlet 并且在 servlet 内部我想要一个 java 方法来获取字符串列表。
YAML 列出了 Java 的推荐库: SnakeYAML, YamlBeans and eo-yaml
其中使用最广泛的可能是 SnakeYAML。 Baeldung 在这里有一个非常容易理解的教程:https://www.baeldung.com/java-snake-yaml
[编辑以解决新代码并在 OP 编辑中输出]:
您使用的格式和命名约定也有一些问题。在你的 yaml 文件中,任何列表都需要 [brackets],实例变量需要是 camelCase,任何字符串都需要用引号括起来(包括 String HashMap 键):
products:
"ProductA":
suite:
"SuiteName_A":
environment_1: ["A","B","C"]
environment_2: ["X","Y","Z"]
"SuiteName_B":
environment_1: ["E","F","G"]
environment_2: ["K","L","M"]
"ProductB":
suite:
"SuiteName_K":
environment_1: ["A1","B2","C3"]
environment_2: ["X1","Y1","Z1"]
您应该尝试在您的 bean 命名约定中匹配它。此外,您的第二个 setter 需要设置 Environment_2 而不是 Environment_1。这是您的实体 类 的外观。
环境
package Configuration;
import java.util.ArrayList;
public class Environment {
private ArrayList<String> environment_1;
private ArrayList<String> environment_2;
public ArrayList<String> getEnvironment_1() {
return environment_1;
}
public void setEnvironment_1(ArrayList<String> environment_1) {
this.environment_1 = environment_1;
}
public ArrayList<String> getEnvironment_2() {
return environment_2;
}
public void setEnvironment_2(ArrayList<String> environment_2) {
this.environment_2 = environment_2;
}
}
套房名称
package Configuration;
import java.util.HashMap;
public class SuiteName {
private HashMap<String,Environment> suite;
public HashMap<String, Environment> getSuite() {
return suite;
}
public void setSuite(HashMap<String, Environment> suite) {
suite = suite;
}
}
package Configuration;
import java.util.HashMap;
public class Product {
private HashMap<String, SuiteName> products;
public HashMap<String, SuiteName> getProducts() {
return products;
}
public void setProducts(HashMap<String, SuiteName> products) {
this.products = products;
}
}
编辑: 在您的主要方法中,您可能希望使用 yaml.load(inputStream) 在 HashMap 中获取整个文件。根据您在评论中提出的问题,我添加了访问数据结构。
数据库类
package Configuration;
import org.yaml.snakeyaml.Yaml;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
public class DbClass {
public static void main(String[] args) throws FileNotFoundException {
Yaml yaml = new Yaml();
InputStream inputStream = new FileInputStream("path.yml");
System.out.println(inputStream);
HashMap yamlMap = yaml.load(inputStream);
for (Object o : yamlMap.entrySet()) {
System.out.println(o);
}
// Access HashMaps and ArrayList by key(s)
HashMap products = (HashMap) yamlMap.get("products");
HashMap product = (HashMap) products.get("ProductA");
HashMap suite = (HashMap) product.get("suite");
HashMap suiteName = (HashMap) suite.get("SuiteName_B");
ArrayList environment = (ArrayList) suiteName.get("environment_1");
System.out.println(environment);
}
}
这是无效的 YAML:
Environment_1: "A","B","C"
你需要做的
Environment_1: ["A","B","C"]
那么,setter的名字有误:
public ArrayList<String> getEnvironment_1() {
return Environment_1;
}
public void setINT(ArrayList<String> Environment_1) {
this.Environment_1 = Environment_1;
}
setter 必须命名为 setEnvironment_1
。这是因为 SnakeYAML 通过它们的 getters & setters.
下一个问题是 YAML 中的名称以大写字母开头。 SnakeYAML 使用 JavaBeans API 来发现属性,这将产生 environment_1
作为 属性 名称,而不是 Environment_1
。您可以通过覆盖 属性 discovery:
final PropertyUtils uppercaseUtils = new PropertyUtils() {
@Override
public Property getProperty(Class<? extends Object> type, String name) throws IntrospectionException {
return super.getProperty(name.substring(0, 1). toLowerCase() + name. substring(1));
}
}
final Constructor c = new Constructor(Product.class);
c.setPropertyUtils(uppercaseUtils);
Yaml yaml = new Yaml(c);