簡體   English   中英

如何從 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"]

已編輯----當我在一些閱讀文章中閱讀時,我創建了一些課程,這里是我想出的..

環境 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

我想獲取環境名稱列表並將其存儲在列表中。 我知道使用 jackson api。 但我不知道如何將 map 這個數據轉給 class。 我正在使用 servlets 並且在 servlet 內部我想要一個 java 方法來獲取字符串列表。

YAML有一個 Java 的推薦庫列表: SnakeYAMLYamlBeanseo-yaml

其中使用最廣泛的可能是 SnakeYAML。 Baeldung在這里有一個非常容易理解的教程: https://www.baeldung.com/java-snake-yaml

[編輯以解決新代碼和 output 由 OP 編輯]:

您使用的格式和命名約定也有一些問題。 在您的 yaml 文件中,任何列表都需要[括號],實例變量需要是駝峰式,任何字符串都需要用引號括起來(包括字符串 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 命名約定中匹配它。 此外,您的第二個設置者需要設置 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"]

然后,二傳手有錯誤的名字:

    public ArrayList<String> getEnvironment_1() {
        return Environment_1;
    }

    public void setINT(ArrayList<String> Environment_1) {
        this.Environment_1 = Environment_1;
    }

設置器必須命名為setEnvironment_1 這是因為 SnakeYAML 通過其 getter 和 setter 訪問私有字段。

下一個問題是 YAML 中的名稱以大寫字母開頭。 SnakeYAML 使用JavaBeans API來發現屬性,這將產生environment_1作為屬性名稱,而不是Environment_1 您可以通過覆蓋屬性發現來解決此問題:

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM