It's common and easy to store application configuration information like key=value in java properties file.
But how to store object or collection of object type into java properties file.
For example, I want to store a list of failed to fetch items in java properties file: including item id, failed times, and some other properties of this item, then I need deserialize it to list of UnableToFetchItem.
unableToFetchList={"id_1"\:{"id"\:"id_1, "extracting"\:a_long_millseconds,"failedTimes"\:a_int}, "id_x":{}, }
If we have to write our own code, it gets troublesome: when serialize the item lists, we have to put delimiter to separate items, serialize key/value pairs; when ddeserialize it back, we have to parse the delimiter, construct item object and set field value.
As my application already uses the java Json library:Gson, so I decide to serialize the list of UnableToFetchItem as a Json string, and then deserialize the Json string to a list of UnableToFetchItem. The code is much simpler and easy to read and maintain.
Implementation
The code is simple, the only trick part is how to serialize and deserialize a list of object:
Look at GSon User Guide: Collections Examples
The key is to define a TypeToken with correct parameterized type:
But how to store object or collection of object type into java properties file.
For example, I want to store a list of failed to fetch items in java properties file: including item id, failed times, and some other properties of this item, then I need deserialize it to list of UnableToFetchItem.
unableToFetchList={"id_1"\:{"id"\:"id_1, "extracting"\:a_long_millseconds,"failedTimes"\:a_int}, "id_x":{}, }
If we have to write our own code, it gets troublesome: when serialize the item lists, we have to put delimiter to separate items, serialize key/value pairs; when ddeserialize it back, we have to parse the delimiter, construct item object and set field value.
As my application already uses the java Json library:Gson, so I decide to serialize the list of UnableToFetchItem as a Json string, and then deserialize the Json string to a list of UnableToFetchItem. The code is much simpler and easy to read and maintain.
Implementation
The code is simple, the only trick part is how to serialize and deserialize a list of object:
Look at GSon User Guide: Collections Examples
The key is to define a TypeToken with correct parameterized type:
private static Type objType = new TypeToken<Map<String,UnableToFetch>>() {}.getType();
import java.lang.reflect.Type; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; public class AppConfig { private Map<String,UnableToFetch> unableToFetchMap = new HashMap<String,UnableToFetch>(); private static Type objType = new TypeToken<Map<String,UnableToFetch>>() {} .getType(); public static Map<String,UnableToFetch> fromJson(String jsonStr) { Map<String,UnableToFetch> result = null; if (StringUtils.isNotBlank(jsonStr)) { result = new Gson().fromJson(jsonStr, objType); } if (result == null) { result = new HashMap<String,UnableToFetch>(); } return result; } public static String toJson(Map<String,UnableToFetch> map) { return new Gson().toJson(map, objType); } public AppConfig readFromPropertiesFile() { File proppertiesFile = new File("PROPERTIES_FILE_NAME"); if (!proppertiesFile.exists()) { return this; } Properties properties = new Properties(); FileInputStream fis = null; try { fis = new FileInputStream(proppertiesFile); properties.load(fis); String str = properties.getProperty("unableToFetchList"); unableToFetchMap = fromJson(str); } catch (Exception e) { throw new RuntimeException(e); } finally { IOUtils.closeQuietly(fis); } return this; } public void saveProperties() { File proppertiesFile = new File("PROPERTIES_FILE_NAME"); Properties properties = new Properties(); FileOutputStream fos = null; try { fos = new FileOutputStream(proppertiesFile); if (unableToFetchMap != null) { properties.setProperty("unableToFetchList", toJson(unableToFetchMap)); } properties.store(fos, null); } catch (Exception e) { throw new RuntimeException(e); } finally { IOUtils.closeQuietly(fos); } } public static void main(String[] args) { Map<String,UnableToFetch> unableToFetchMap = new HashMap<String,UnableToFetch>(); unableToFetchMap.put("id1", new UnableToFetch("id1", 1, 11111)); String jsonStr = AppConfig.toJson(unableToFetchMap); System.out.println(jsonStr); unableToFetchMap = AppConfig.fromJson(jsonStr); jsonStr = AppConfig.toJson(unableToFetchMap); System.out.println(jsonStr); } public static class UnableToFetch { private String id; private long along; private int failedTimes; public UnableToFetch() {} public String toString() { return ToStringBuilder.reflectionToString(this); } } }