In the Java world, configuration is left to Properties, and this module dates back to the old JDK1.0.
“Oh my God, this is 20 years ago and I still use Properties…”
However, the main character of this article is not Properties, but Yaml.
This is the darling of the new era of microservices architecture, and Yaml is a bit of a bandit compared to Properties. Properties profiles can be found in most previous projects, including for business property configuration, machine-machine interface interaction, internationalization, and so on. And in a few cases, there are some “hybrid” practices, such as:
-
Use Xml to represent some templates
-
Use a JSON-formatted string
-
Streaking text format, application self-parsing…
Mixed configuration often occurs in projects with a “bad taste” because code is stale, stale, and so on, and it is difficult to form a unified approach. However, apart from the simple configuration method of the Properties property file, the other methods are nothing more than to adapt to the complex and diversified requirements of configuration.
Yaml, then, is designed for this scenario, and much of the official SpringBoot documentation uses the configuration format of the Yaml syntax. Here is an introduction to Yaml and how it is used.
What is Yaml
Definition from encyclopedia:
“Yaml is a readable, easy-to-use data serialization format first published by Clark Evans in 2001.”
You can see that Yaml is not a very new thing, but not many people in the past. In addition, Yaml is supported by a variety of programming languages and frameworks with high versatility. In the Java architecture, common microservices frameworks support or even recommend Yaml as the preferred configuration language.
What is special about Yaml itself? Take a look at the following example:
environments:
dev:
url: https://dev.example.com
name: Developer Setup
prod:
url: https://another.example.com
name: My Cool App
Copy the code
This syntax is equivalent to Properties:
environments.dev.url=https://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=https://another.example.com
environments.prod.name=My Cool App
Copy the code
As you can see, YAML is more structured and better suited for expressing an object. Syntactically it has the following characteristics:
-
Case sensitivity
-
The use of space indentation for hierarchy, rather than the Tab key, is mainly due to the need to align text on different platforms
-
The number of Spaces indented does not matter, as long as elements of the same rank are aligned to the left
-
Use a # as a comment line
-
Use a hyphen (-) to describe array elements
Comparing the Properties
Properties is a good way to implement key-value configuration, including as a way to configure some international content. However, it is difficult for Properties to show multi-level nested relationships, and Yaml can make up for this shortcoming.
Compared to Json
Yaml and Json are both structured expression languages, but Json was designed to be easy to use and easy to transfer. Yaml, on the other hand, focuses on readability (and more on appearance), almost as a “superset” of Json, a more readable (and prettier) structured format.
In addition, Json is easier to generate and parse, and is suitable for transfer and interaction in a variety of cross-language, distributed environments. Yaml, meanwhile, is generally used for more configurations.
The definition of Yaml can be accessed at the following address:
http://www.yaml.org/spec/1.2/spec.html
Yaml syntax
Yaml is very compact and defines only three elements:
-
Object: a collection of key-value pairs corresponding to a Java HashMap
-
Array: AN ordered set of values, corresponding to a List in Java
-
1. A single, nondivisible value, such as 3, “Jackson”.
How objects are represented
Properties of an object, nesting relationships are represented by indented space alignment as follows:
article:
Title: A man's confession
author:
Name: Chen ling
gender: female
Copy the code
How to represent an array
The elements of the array are represented by a hyphen (-), as follows:
article:
Title: A man's confession
tags:
Biography -
- social
- people
Copy the code
The basic unit that makes up the contents of an object or array is a single value. Yaml supports seven types of single values:
type | sample |
---|---|
string | Bob |
Boolean value | true |
The integer | 199 |
Floating point Numbers | 19.91 |
Null | ~ |
time | The 2001-12-14 T22:14:09. 10 + 08:00 |
The date of | 2019-01-09 |
Among them, the date, time, using the ISO 8601 international standard format, about the definition of it can refer to: https://www.w3.org/TR/NOTE-datetime
Typically, a single value ends on a line. However, if you encounter a multi-line string, you can use some special characters, such as:
text: |
Hello
World
Copy the code
The corresponding results are:
{ text: 'Hello\nWorld\n' }
Copy the code
We can use + to preserve the end of the string and – to remove the end of the string:
text1: |+
Hello
text2: |-
Hello
Copy the code
The corresponding results are:
{ text1: 'Hello\n\n\n', text2: 'Hello' }
Copy the code
In addition, Yaml supports advanced uses such as references, functions, and regular expressions, which are rarely used on projects.
3. Operate Yaml
The common component currently used to manipulate Yaml is Snake Yaml, which supports the standard Yaml 1.1 version.
The Official SpringBoot documentation also describes how to integrate the framework at the following address: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-loading-yaml
A sample of integrating SnakeYaml into a project is provided below.
A. Introduce frameworks
In Maven’s POM.xml file add:
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
< version > 1.21 < / version >
</dependency>
Copy the code
B. Code snippets
Implement loading the configuration file
The following code loads the YAML configuration from the classpath config.yml file:
InputStream inputStream = YamlUtil.class.getClassLoader()
.getResourceAsStream("config.yml");
Yaml yaml = new Yaml();
Map<String, Object> objectMap = yaml.load(inputStream);
System.out.println(objectMap.get("path"));
Copy the code
Implementing object conversion
Define the following Pojo objects:
public static class A{
private String name = "hello";
private List<B> bs = new ArrayList<B>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<B> getBs() {
return bs;
}
public void setBs(List<B> bs) {
this.bs = bs;
}
}
public static class B{
private String id = UUID.randomUUID().toString();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Copy the code
Code to output an object in Yaml format via SnakeYaml:
A a = new A();
a.getBs().add(new B());
a.getBs().add(new B());
Yaml yaml = new Yaml();
String aString = yaml.dumpAsMap(a);
System.out.println(aString);
Copy the code
The following output is displayed:
bs:
- id: b3688f05-ea7e-436b-bc9a-9c5df555c7fd
- id: 7906224d-8ecc-43b8-bc3b-07985bc18ebd
name: hello
Copy the code
At this point, if you want to reverse the Yaml text to an A object, you can execute the following code:
A a1 = new Yaml().parseToObject(aString, A.class);
.
Copy the code
C. Complete case
Finally, we can encapsulate the operations of Yaml documents as a utility class that can be easily integrated into business code.
YamlUtil.java
public class YamlUtil {
/ * *
Load content from a resource file and parse it into a Map object
*
* @param path
* @return
* /
public static Map< String, Object> loadToMap( String path) {
if (StringUtils.isEmpty(path)) {
return Collections.emptyMap();
}
InputStream inputStream = YamlUtil. class.getClassLoader()
.getResourceAsStream(path);
Yaml yaml = new Yaml();
Map
objectMap = yaml.load(inputStream);
,>
return objectMap;
}
/ * *
* Parse strings into Map objects
*
* @param content
* @return
* /
public static Map< String, Object> parseToMap( String content) {
if (StringUtils.isEmpty(content)) {
return Collections.emptyMap();
}
Yaml yaml = new Yaml();
Map
objectMap = yaml.load(content);
,>
return objectMap;
}
/ * *
* Parse a string into a class object
*
* @param content
* @param clazz
* @param <T>
* @return
* /
public static
T parseToObject( String content, Class
clazz) {
if (StringUtils.isEmpty(content) || clazz == null) {
return null;
}
Yaml yaml = new Yaml( new Constructor(clazz));
T object = yaml.load(content);
return object;
}
/ * *
* Formatting objects
*
* @param object
* @return
* /
public static String format( Object object) {
Yaml yaml = new Yaml();
return yaml.dumpAsMap( object);
}
}
Copy the code
At this point, we are done reading and writing Yaml. Of course, in addition to Snake Yaml, you can also use the popular Jackson component to accomplish similar functions. I won’t go into too much detail here, but you can try it out for yourself.
Reference documentation
Ruan Yifeng -YAML Language Tutorial:
http://www.ruanyifeng.com/blog/2016/07/yaml.html
SnakeYaml Official documentation:
https://bitbucket.org/asomov/snakeyaml/wiki/Documentation
Yaml 1.2 specification:
http://www.yaml.org/spec/1.2/spec.html
SpringBoot-LoadingYaml
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-loading-yaml
Check out the Coder’s SpringBoot tutorial series