Introduction
YAML is most useful data format to describe structural hierarchy in these days. It’s more simple and collision resistant.
It is useful to describe your configuration attributes in your developments.
We are going to learn to manage configuration YAML in Java programmatically.
For our goal, we will use SnakeYAML library.
OK, Let’s dive in.
Set up environment
- At first We need to choose development tool. Even if any development IDE for Java could be used, but I would use Visual Studio Code that have been hotted on these days.
- Setting dependency to build.gradle file. if you do like below, It’s would be configured classpath automatically.
dependencies {
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
// https://mvnrepository.com/artifact/org.yaml/snakeyaml
compile group: 'org.yaml', name: 'snakeyaml', version: '1.27'
}
Enter fullscreen mode Exit fullscreen mode
- All of environment setting is over doing this.
Let’s go to code
First, we need to define configuration on config.yml file formatted with YAML.
adminPassword: 1234
adminPort: 9292
adminUser: admin
forbiddenRemote: []
host: localhost
sessions:
Oracle:
allowedHosts: [127.0.0.1]
connectionTimeout: 3
remoteHosts: [192.168.1.152:1521]
retry: 3
Kafka:
allowedHosts: [127.0.0.1]
connectionTimeout: 3
remoteHosts: [192.168.1.153:2181]
retry: 3
Enter fullscreen mode Exit fullscreen mode
Second, we have to write Java Bean code mapping with config.yml fields. Top object of configuration is implemented to Config.java.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Config {
private String adminPassword;
private String adminUser;
private String host;
private int adminPort;
private List<String> forbiddenRemote = new ArrayList<>();
private Map<String, Sessions> sessions = new HashMap<>();
Config() {}
public String getAdminUser() {
return adminUser;
}
public void setAdminUser(String adminUser) {
this.adminUser = adminUser;
}
public String getAdminPassword() {
return adminPassword;
}
public void setAdminPassword(String adminPassword) {
this.adminPassword = adminPassword;
}
public int getAdminPort() {
return adminPort;
}
public void setAdminPort(int adminPort) {
this.adminPort = adminPort;
}
public String getHost() {
return this.host;
}
public void setHost(String host) {
this.host = host;
}
public List<String> getForbiddenRemote() {
return forbiddenRemote;
}
public void setForbiddenRemote(List<String> forbiddenRemote) {
this.forbiddenRemote = forbiddenRemote;
}
public Map<String, Sessions> getSessions() {
return sessions;
}
public void setSessions(Map<String, Sessions> sessions) {
this.sessions = sessions;
}
public Sessions getSessions(String sessionName) {
return this.sessions.get(sessionName);
}
@Override
public String toString() {
return "Config [adminUser=" + adminUser + ", adminPassword=" + adminPassword + ", host=" + host
+ ", adminPort=" + adminPort + ", forbiddenRemote=" + forbiddenRemote + ", sessions="
+ sessions + "]";
}
}
Enter fullscreen mode Exit fullscreen mode
Sub classification of Config object is Sessions object. It will be placed it’s own to Config object’s sessions field as Map element.
import java.util.List;
public class Sessions {
List<String> allowedHosts;
int connectionTimeout;
List<String> remoteHosts;
int retry;
public Sessions() {
}
public List<String> getAllowedHosts() {
return allowedHosts;
}
public void setAllowedHosts(List<String> allowedHosts) {
this.allowedHosts = allowedHosts;
}
public int getConnectionTimeout() {
return connectionTimeout;
}
public void setConnectionTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public List<String> getRemoteHosts() {
return remoteHosts;
}
public void setRemoteHosts(List<String> remoteHosts) {
this.remoteHosts = remoteHosts;
}
public int getRetry() {
return retry;
}
public void setRetry(int retry) {
this.retry = retry;
}
@Override
public String toString() {
return "Sessions [allowedHosts=" + allowedHosts + ", connectionTimeout=" + connectionTimeout + ", remoteHosts="
+ remoteHosts + ", retry=" + retry + "]";
}
}
Enter fullscreen mode Exit fullscreen mode
Now, we need to write Handler source file to load config.yml’s contents to Java Beans objects we wrote before. To do this, we have to use SnakeYAML library and it’s example down below.
Path configPath = Paths.get("./config.yml");
//At first, construct Constructor object using Config.class root object of contents.
Constructor constructor = new Constructor(Config.class);
//Construct Yaml object with constructor object.
Yaml yaml = new Yaml(constructor);
//And then load by given Stream object specified of config.yml file.
yaml.load(new FileInputStream(configPath.toFile()));
Enter fullscreen mode Exit fullscreen mode
Also, If we want to dump contents of Config object in memory to file, we should write dumping code like below.
Path configPath = Paths.get("./config.yml");
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(FlowStyle.BLOCK);
options.setPrettyFlow(true);
Yaml yml = new Yaml(options);
yml.dump(this.config, new FileWriter(configPath.toFile()));
Enter fullscreen mode Exit fullscreen mode
As setting detail options of DumperOptions object, we can handle YAML content for what we want.
We could write Handler to improve for our purpose, then will go to complete Handler code to ConfigHandler.java.
ConfigHandler object will be Singleton style for calling wherever we want in our application. and will have functionality of loading, dumping and referring Config object.
Complete ConfigHandler.java code is down below.
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
public class ConfigHandler {
public static final Path configPath = Paths.get("./config.yml");
private static ConfigHandler configHandler;
Config config;
/** * Get instance of ConfigHandler * @return * @throws FileNotFoundException */
public static ConfigHandler getInstance() throws FileNotFoundException {
return getInstance(configPath);
}
/** * Get instance of ConfigHandler * @param configPath * @return * @throws FileNotFoundException */
public static ConfigHandler getInstance(Path configPath) throws FileNotFoundException {
if(configHandler == null) {
configHandler = new ConfigHandler(configPath);
}
return configHandler;
}
/** * Constructor * @param configPath * @throws FileNotFoundException */
private ConfigHandler(Path configPath) throws FileNotFoundException {
this.config = loadConfig(configPath);
}
/** * Load config.yml * @param configPath * @throws FileNotFoundException */
public Config loadConfig(Path configPath) throws FileNotFoundException {
Constructor constructor = new Constructor(Config.class);
Yaml yaml = new Yaml(constructor);
return yaml.load(new FileInputStream(configPath.toFile()));
}
/** * Dump config to config.yml * @throws IllegalArgumentException * @throws IllegalAccessException * @throws IOException */
public void dumpConfig() throws IllegalArgumentException, IllegalAccessException, IOException {
dumpConfig(this.config, this.configPath);
}
/** * Dump config to config.yml * @param configPath * @throws IllegalArgumentException * @throws IllegalAccessException * @throws IOException */
public void dumpConfig(Config config, Path configPath) throws IllegalArgumentException, IllegalAccessException, IOException {
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(FlowStyle.BLOCK);
options.setPrettyFlow(true);
Yaml yml = new Yaml(options);
yml.dump(config, new FileWriter(configPath.toFile()));
}
/** * Get config object * @return */
public Config getConfig() {
return this.config;
}
/** * Get session mapping object by session name * @param sessionName * @return */
public Sessions getSessions(String sessionName) {
return this.config.getSessions().get(sessionName);
}
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, IOException, NoSuchFieldException, SecurityException {
ConfigHandler handler = ConfigHandler.getInstance();
Config config = handler.getConfig();
System.out.println("ADMIN: "+config.getAdminUser());
System.out.println("PASSWD: "+config.getAdminPassword());
System.out.println("ORACLE: "+config.getSessions("Oracle").toString());
config.setAdminPassword("123456789");
handler.dumpConfig();
}
}
Enter fullscreen mode Exit fullscreen mode
Conclusion
YAML is most simple and very fine format to manage contents.
Easy readability and Structural expression is proving why it’s famous in these days.
For the more, we could use this format to generate huge data files of Java Bean data for Business or Analysis on Big-Data Store.
All of elastic thinking is yours.
Thanks.
原文链接:How to manage your configuration file with YAML in Java programmatically
暂无评论内容