Intro.
Some far ago, I've been introducing 'How to manage your configuration file with YAML in Java programmatically' in previous post.
if you wanna know it, follow link: How to manage your configuration file with YAML in Java programmatically
It was about handing Yaml file contents to create Java Bean object. That was including information of a configuration or serialized Valued-Object(VO). Simply to say, It was about load or dump information between Yaml file and Java object.
Meanwhile, Someone who has keen thinking asked how to access a Yaml file in internal resources?
So I realized it's need,
Here I would show how to load and dump Yaml file in Jar.
Setting up environments.
- As same as previous post, To handle Yaml file, We need SnakeYAML library.
- For our works, Any IDE Tools is able to use, But I gonna to use Visual Studio Code(VSCODE) on fever in these days.
- And we have to set SnakeYAML MAVEN dependency to POM.xml. In previous post I used Gradle but now, Would use MAVEN for diversity :)
- If you are prepared with above things, Readied to start coding.
Designing Java Class.
Before we gonna see implemented code, I would show you entire design of our works.
- We will define java class named "YamlInternalHandler" to handle Yaml file in Jar.
- Will define two method named "loadInternalJar" and "dumpInternalJar". First one is to load Yaml's contents to Java object with jar entry path and a Class object to be loaded the contents. Second one is to dump a object values to Yaml file in Jar with jar entry path and instance of Java object including a values.
- We could load and dump a specified object mapping with a Yaml file in jar. Surely, It's good to make sure syntax of Yaml file in Jar.
Let's dive into code.
Contents of Yaml file in Jar is down below.
firstName: Kooin
lastName: Shin
age: 48
profile:
- character: bright
hobby: claiming
address: Seoul
postalCode: 123
- character: delight
hobby: ski
address: Seoul
postalCode: 123
Java Bean to be loaded contents is 'Customer' and 'Profile' representing Yaml's values.
package org.chaostocosmos.doc.yml;
import java.util.List;
public class Customer {
private String firstName;
private String lastName;
private int age;
private List<Profile> profile;
public Customer() {}
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
public List<Profile> getProfile() {
return this.profile;
}
public void setProfile(List<Profile> profile) {
this.profile = profile;
}
@Override
public String toString() {
return "{" +
" firstName='" + firstName + "'" +
", lastName='" + lastName + "'" +
", age='" + age + "'" +
", profile='" + profile + "'" +
"}";
}
}
package org.chaostocosmos.doc.yml;
public class Profile {
String character;
String hobby;
String address;
int postalCode;
public Profile() {}
public String getCharacter() {
return this.character;
}
public void setCharacter(String character) {
this.character = character;
}
public String getHobby() {
return this.hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public int getPostalCode() {
return this.postalCode;
}
public void setPostalCode(int postalCode) {
this.postalCode = postalCode;
}
@Override
public String toString() {
return "{" +
" character='" + character + "'" +
", hobby='" + hobby + "'" +
", address='" + address + "'" +
", postalCode='" + postalCode + "'" +
"}";
}
}
And Now we gonna show core code of 'YamlInternalHandler' class.
package org.chaostocosmos.doc.yml;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.constructor.Constructor;
/**
* Yaml Internal Handler
*
* @author Kooin-Shin
* @since 2021.01.04
*/
public class YamlInternalHandler {
/**
* Jar file having yaml file
*/
File file;
/**
* Constructor
* @param file
* @throws IOException
*/
public YamlInternalHandler(File file) throws IOException {
this.file = file;
}
/**
* Load object from internal yaml file in jar
* @param jarEntry
* @param clazz
* @return
* @throws IOException
*/
public Object loadInternalJar(String jarEntry, Class<? extends Object> clazz) throws IOException {
if (!jarEntry.endsWith(".yml")) {
throw new IllegalArgumentException("This component only support a yaml file in jar!!!");
}
JarFile jarFile = new JarFile(this.file); //Create JarFile object
JarEntry entry = jarFile.getJarEntry(jarEntry); //Get JarEntry specified by first parameter
InputStream is = jarFile.getInputStream(entry); //Get InputStream from JarFile by JarEntry
Constructor constructor = new Constructor(clazz); //Create Constructor object specified by second parameter
Yaml yaml = new Yaml(constructor); //Create Yaml object with Constructor object
Object obj = yaml.load(is); //Load contents to object instance
is.close(); //Close InputStream
jarFile.close(); //Close JarFile
return obj;
}
/**
* Dump object to yaml file in jar
* @param jarEntry
* @param obj
* @throws FileNotFoundException
* @throws IOException
*/
public void dumpInternalJar(String jarEntry, Object obj) throws FileNotFoundException, IOException {
JarOutputStream jos = new JarOutputStream(new FileOutputStream(this.file)); //Create JarOutputStream object
jos.putNextEntry(new ZipEntry(jarEntry)); //Put jar entry by first parameter
DumperOptions options = new DumperOptions(); //Set dump options
options.setDefaultFlowStyle(FlowStyle.BLOCK);
options.setPrettyFlow(true);
Yaml yaml = new Yaml(options); //Create Yaml object with DumperOptions object
yaml.dump(obj, new OutputStreamWriter(jos)); //Dump contents of second parameter
jos.close(); // Close JarOutputStream
}
public static void main(String[] args) throws IOException {
File file = new File("D:\\Projects\\chaos-commons\\yaml.jar");
YamlInternalHandler ymlHandler = new YamlInternalHandler(file);
Customer customer = (Customer) ymlHandler.loadInternalJar("tmp/yaml/Customer.yml", Customer.class);
System.out.println(customer.toString());
customer.setFirstName("Jim ");
customer.getProfile().get(0).setAddress("Busan");
ymlHandler.dumpInternalJar("tmp/yaml/Customer.yml", customer);
}
}
Conclusion
Above code is assumed very simple cases of accessing of a Yaml in Jar. As a situation, It can be transformed, modified and improved.
Always elastic thinking is yours!!!
Good Luck!!!
Top comments (0)