java properties to json
Solution 1
Not the easy way, but I managed to do that using Gson
library. The result will be in the
jsonBundle
String. Here we getting the properties or bundles in this case:
final ResourceBundle bundle = ResourceBundle.getBundle("messages");
final Map<String, String> bundleMap = resourceBundleToMap(bundle);
final Type mapType = new TypeToken<Map<String, String>>(){}.getType();
final String jsonBundle = new GsonBuilder()
.registerTypeAdapter(mapType, new BundleMapSerializer())
.create()
.toJson(bundleMap, mapType);
For this implementation ResourceBundle
have to be converted to Map
containing String
as a key and String
as a value.
private static Map<String, String> resourceBundleToMap(final ResourceBundle bundle) {
final Map<String, String> bundleMap = new HashMap<>();
for (String key: bundle.keySet()) {
final String value = bundle.getString(key);
bundleMap.put(key, value);
}
return bundleMap;
}
I had to create custom JSONSerializer
using Gson
for Map<String, String>
:
public class BundleMapSerializer implements JsonSerializer<Map<String, String>> {
private static final Logger LOGGER = LoggerFactory.getLogger(BundleMapSerializer.class);
@Override
public JsonElement serialize(final Map<String, String> bundleMap, final Type typeOfSrc, final JsonSerializationContext context) {
final JsonObject resultJson = new JsonObject();
for (final String key: bundleMap.keySet()) {
try {
createFromBundleKey(resultJson, key, bundleMap.get(key));
} catch (final IOException e) {
LOGGER.error("Bundle map serialization exception: ", e);
}
}
return resultJson;
}
}
And here is the main logic of creating JSON:
public static JsonObject createFromBundleKey(final JsonObject resultJson, final String key, final String value) throws IOException {
if (!key.contains(".")) {
resultJson.addProperty(key, value);
return resultJson;
}
final String currentKey = firstKey(key);
if (currentKey != null) {
final String subRightKey = key.substring(currentKey.length() + 1, key.length());
final JsonObject childJson = getJsonIfExists(resultJson, currentKey);
resultJson.add(currentKey, createFromBundleKey(childJson, subRightKey, value));
}
return resultJson;
}
private static String firstKey(final String fullKey) {
final String[] splittedKey = fullKey.split("\\.");
return (splittedKey.length != 0) ? splittedKey[0] : fullKey;
}
private static JsonObject getJsonIfExists(final JsonObject parent, final String key) {
if (parent == null) {
LOGGER.warn("Parent json parameter is null!");
return null;
}
if (parent.get(key) != null && !(parent.get(key) instanceof JsonObject)) {
throw new IllegalArgumentException("Invalid key \'" + key + "\' for parent: " + parent + "\nKey can not be JSON object and property or array in one time");
}
if (parent.getAsJsonObject(key) != null) {
return parent.getAsJsonObject(key);
} else {
return new JsonObject();
}
}
In the end, if there were a key person.name.firstname
with value John
, it will be converted to such JSON
:
{
"person" : {
"name" : {
"firstname" : "John"
}
}
}
Hope this will help :)
Solution 2
Using lightbend config java library (https://github.com/lightbend/config)
String toHierarchicalJsonString(Properties props) {
com.typesafe.config.Config config = com.typesafe.config.ConfigFactory.parseProperties(props);
return config.root().render(com.typesafe.config.ConfigRenderOptions.concise());
}
Solution 3
It is pretty easy, download and add to your lib: https://code.google.com/p/google-gson/
Gson gsonObj = new Gson();
String strJson = gsonObj.toJson(yourObject);
Solution 4
You can try with https://github.com/mikolajmitura/java-properties-to-json
You can generate Json from:
- from Java properties (java.util.Properties)
- from Map (import java.util.Map) -> Map<String,String>
- from Map (import java.util.Map) -> Map<String,Object>
- from InputStream with properties (java.io.InputStream)
- from given file localization with properties
- from File with properties (java.io.File)
code example:
import pl.jalokim.propertiestojson.util.PropertiesToJsonConverter;
...
Properties properties = ....;
String jsonFromProperties = new PropertiesToJsonConverter().convertToJson(properties);
InputStream inputStream = ....;
String jsonFromInputStream = new PropertiesToJsonConverter().convertToJson(inputStream);
Map<String,String> mapProperties = ....;
String jsonFromInputProperties = new PropertiesToJsonConverter().convertToJson(mapProperties);
Map<String, Object> valuesAsObjectMap = ....;
String jsonFromProperties2 = new PropertiesToJsonConverter().convertFromValuesAsObjectMap(valuesAsObjectMap);
String jsonFromFilePath = new PropertiesToJsonConverter().convertPropertiesFromFileToJson("/home/user/file.properties");
String jsonFromFile = new PropertiesToJsonConverter().convertPropertiesFromFileToJson(new File("/home/user/file.properties"));
maven dependency:
<dependency>
<groupId>pl.jalokim.propertiestojson</groupId>
<artifactId>java-properties-to-json</artifactId>
<version>5.1.0</version>
</dependency>
dependency required minimum java 8.
more example of uses on https://github.com/mikolajmitura/java-properties-to-json
Solution 5
I didn't want any dependency on gson and I wanted to return a hierarchical json from a Spring controller so a deep Map was enough for me.
This works for me, just loop over all your keys and pass in an empty map.
void recurseCreateMaps(Map<String, Object> currentMap, String key, String value) {
if (key.contains(".")) {
String currentKey = key.split("\\.")[0];
Map<String, Object> deeperMap;
if (currentMap.get(currentKey) instanceof Map) {
deeperMap = (Map<String, Object>) currentMap.get(currentKey);
} else {
deeperMap = new HashMap<>();
currentMap.put(currentKey, deeperMap);
}
recurseCreateMaps(deeperMap, key.substring(key.indexOf('.') + 1), value);
} else {
currentMap.put(key, value);
}
}
Vitali Bichov
Updated on August 11, 2020Comments
-
Vitali Bichov over 3 years
Is there an easy way to convert properties with dot notation to json
I.E
server.host=foo.bar server.port=1234
TO
{ "server": { "host": "foo.bar", "port": 1234 } }
-
Ostap Maliuvanchuk almost 10 yearsThe guy need to convert properties to JSON. Not just read json from file to JsonObject.
-
Vitali Bichov almost 10 yearsthe result is: {"server.host":"foo.bar","server.port":1234} but I want to created a hierarchical json
-
Vitali Bichov almost 10 yearsAgain, this converts properties to flat json, I'm looking for something that creates hierarchical json
-
Rocky Hu over 9 yearsHi, Yuriy, I used Gjson2.3 and have the exception Exception in thread "main" java.lang.ClassCastException: com.google.gson.JsonPrimitive cannot be cast to com.google.gson.JsonObject at com.google.gson.JsonObject.getAsJsonObject(JsonObject.java:182) at tools.BundleMapSerializer.getJsonIfExists(BundleMapSerializer.java:67)
-
yyunikov over 9 yearsThe problem is that the object in properties can not be the primitive and JSON object at the same time, so you need to avoid key duplicates like: key.name.a=something, key.name=something2
-
Rocky Hu over 9 yearsyes, you are right, I found my problem, just like you said
-
Martijn Pieters almost 8 yearsYou may want to read How to offer personal open-source libraries? before posting about your project some more.
-
abdelrahman-sinno about 7 yearsI really need this for java 7 !
-
xman_bsn about 4 yearsHi Martijn, just wondering how to keep the original order of properties file elements by using PropertiesToJsonConverter().convertPropertiesFromFileToJson()? This method always returns JSON content in a descending order. Would that be configurable? Many thanks!
-
Mikołaj Mitura about 4 years@xman_bsn this is not configurable, real key properties order is lost by "properties.load(inputStream);" under the hood. but at this moment you can do you implementation of PropertyKeysOrderResolver code below: PropertiesToJsonConverter converter = new PropertiesToJsonConverter(); converter.setPropertyKeysOrderResolver(new PropertyKeysOrderResolver() { public List<String> getKeysInExpectedOrder(Map<String, ?> properties) { // TODO implement way how you want gather properties key order } });
-
Mikołaj Mitura almost 4 yearsfrom 5.1.3 version order of properties in json structure is the same like in the properties file. Converting from Map or Properties class directly order of properties will not be kept.