web123456

java yaml_JAVA implements parsing and serializing YAML based on SnakeYAML

This article mainly introduces JAVA's implementation of parsing and serialization based on SnakeYAMLYAML, The article introduces the example code in detail, which has certain reference value for everyone's study or work. Friends who need it can refer to it

1. Overview

In this article, we will learn how to use the SnakeYAML library to

Convert YAML documents to Java objects, and how JAVA objects are serialized into YAML documents.

2. Project settings

To use SnakeYAML in your project, you need to addMavenDependencies (the latest version can be found here):

snakeyaml

1.25

3. Entrance point

The YAML class is the entry point of the API:

Yaml yaml = new Yaml()

Since the implementation is not thread-safe, different threads must have their own Yaml instance.

4. Loading YAML Document

SnakeYAML support fromStringOr InputStream to load the document, we start by defining a simple YAML document and then name the file:

firstName: "John"

lastName: "Doe"

age: 20

4.1 Basic usage

Now we will use the Yaml class to parse the above YAML documentation:

Yaml yaml = new Yaml();

InputStream inputStream = ()

.getClassLoader()

.getResourceAsStream("");

Map obj = (inputStream);

(obj);

The above code generates the following output:

{firstName=John, lastName=Doe, age=20}

By default, the load() method returns a Map object. When querying Map objects, we need to know the name of the attribute key in advance, otherwise errors are prone to occur. A better approach is to customize the type.

4.2 Custom type analysis

SnakeYAML provides a way to parse documents into custom types

Let's define a Customer class and try to load the document again:

public class Customer {

private String firstName;

private String lastName;

private int age;

// getters and setters

}

Now I'll load:

Yaml yaml = new Yaml();

InputStream inputStream = ()

.getClassLoader()

.getResourceAsStream("");

Customer customer = (inputStream);

Another way is to use the Constructor:

Yaml yaml = new Yaml(new Constructor());

4.3 Implicit Types

If no type is defined for a given property, the library automatically converts the value to an implicit type.

For example:

1.0 -> Float

42 -> Integer

2009-03-30 -> Date

Let's use a TestCase to test this implicit type conversion:

@Test

public void whenLoadYAML_thenLoadCorrectImplicitTypes() {

Yaml yaml = new Yaml();

Map document = ("3.0: 2018-07-22");

assertNotNull(document);

assertEquals(1, ());

assertTrue((3.0d));

}

4.4 Nested Objects

SnakeYAML supports nested complex types.

Let's add the Contact and Address details to " " and save the new file as customer_with_contact_details_and_address.yaml.

Now we will analyze the new YAML documentation:

firstName: "John"

lastName: "Doe"

age: 31

contactDetails:

- type: "mobile"

number: 123456789

- type: "landline"

number: 456786868

homeAddress:

line: "Xyz, DEF Street"

city: "City Y"

state: "State Y"

zip: 345657

Let's update the java class:

public class Customer {

private String firstName;

private String lastName;

private int age;

private List contactDetails;

private Address homeAddress;

// getters and setters

}

public class Contact {

private String type;

private int number;

// getters and setters

}

public class Address {

private String line;

private String city;

private String state;

private Integer zip;

// getters and setters

}

Now, let's test Yaml#load():

@Test

public void

whenLoadYAMLDocumentWithTopLevelClass_thenLoadCorrectJavaObjectWithNestedObjects() {

Yaml yaml = new Yaml(new Constructor());

InputStream inputStream = ()

.getClassLoader()

.getResourceAsStream("yaml/customer_with_contact_details_and_address.yaml");

Customer customer = (inputStream);

assertNotNull(customer);

assertEquals("John", ());

assertEquals("Doe", ());

assertEquals(31, ());

assertNotNull(());

assertEquals(2, ().size());

assertEquals("mobile", ()

.get(0)

.getType());

assertEquals(123456789, ()

.get(0)

.getNumber());

assertEquals("landline", ()

.get(1)

.getType());

assertEquals(456786868, ()

.get(1)

.getNumber());

assertNotNull(());

assertEquals("Xyz, DEF Street", ()

.getLine());

}

4.5 Type-safe collections

When one or more properties of a given Java class are generic collection classes, the generic type needs to be specified through TypeDescription so that it can be parsed correctly.

Let's assume that a Customer has multiple Contacts:

firstName: "John"

lastName: "Doe"

age: 31

contactDetails:

- { type: "mobile", number: 123456789}

- { type: "landline", number: 123456789}

To be able to parse correctly, we can specify TypeDescription for a given property on the top-level class:

Constructor constructor = new Constructor();

TypeDescription customTypeDescription = new TypeDescription();

("contactDetails", );

(customTypeDescription);

Yaml yaml = new Yaml(constructor);

4.6 Load multiple files

In some cases, there may be multiple YAML documents in a single file, and we want to parse all documents. The YAML class provides a LOADALL() method to complete the parsing of this type.

Suppose the following is in a file:

---

firstName: "John"

lastName: "Doe"

age: 20

---

firstName: "Jack"

lastName: "Jones"

age: 25

We can use the loadAll() method to parse the above, as shown in the following code example:

@Test

public void whenLoadMultipleYAMLDocuments_thenLoadCorrectJavaObjects() {

Yaml yaml = new Yaml(new Constructor());

InputStream inputStream = ()

.getClassLoader()

.getResourceAsStream("yaml/");

int count = 0;

for (Object object : (inputStream)) {

count++;

assertTrue(object instanceof Customer);

}

assertEquals(2,count);

}

5. Generate YAML file

SnakeYAML supports serializing java objects into yml.

5.1 Basic usage

We will start with a simple example of dumping an instance of a Map into a YAML document (String):

@Test

public void whenDumpMap_thenGenerateCorrectYAML() {

Map data = new LinkedHashMap();

("name", "Silenthand Olleander");

("race", "Human");

("traits", new String[] { "ONE_HAND", "ONE_EYE" });

Yaml yaml = new Yaml();

StringWriter writer = new StringWriter();

(data, writer);

String expectedYaml = "name: Silenthand Olleander\nrace: Human\ntraits: [ONE_HAND, ONE_EYE]\n";

assertEquals(expectedYaml, ());

}

The above code produces the following output (note that instances using LinkedHashMap will preserve the order in which the output data is output):

name: Silenthand Olleander

race: Human

traits: [ONE_HAND, ONE_EYE]

5.2 Custom Java Objects

We also have the option to dump custom Java types into the output stream.

@Test

public void whenDumpACustomType_thenGenerateCorrectYAML() {

Customer customer = new Customer();

(45);

("Greg");

("McDowell");

Yaml yaml = new Yaml();

StringWriter writer = new StringWriter();

(customer, writer);

String expectedYaml = "!! {age: 45, contactDetails: null, firstName: Greg,\n homeAddress: null, lastName: McDowell}\n";

assertEquals(expectedYaml, ());

}

The generated content will contain !!, To avoid using tag names in the output file, we can use the dumpAs() method provided by the library.

So, in the above code, we can make the following adjustments to remove the tag:

(customer, , null);

Six Conclusion

This article describes the SnakeYAML library parsing and serializing YAML documents.

All examples can be found in the GitHub project.

The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support it.