Existe-t-il un moyen simple de convertir des propriétés avec notation par points en json
C'EST À DIRE
server.Host=foo.bar
server.port=1234
À
{
"server": {
"Host": "foo.bar",
"port": 1234
}
}
Ce n’est pas facile, mais j’ai réussi à le faire en utilisant la bibliothèque Gson
. Le résultat sera dans la chaîne jsonBundle
. Ici, nous obtenons les propriétés ou les lots dans ce cas:
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);
Pour cette implémentation, ResourceBundle
doit être converti en Map
contenant String
en tant que clé et String
en tant que valeur.
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;
}
Je devais créer une JSONSerializer
personnalisée en utilisant Gson
pour 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;
}
}
Et voici la logique principale de la création de 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();
}
}
En fin de compte, s'il existe une clé person.name.firstname
avec la valeur John
, elle sera convertie en une telle JSON
:
{
"person" : {
"name" : {
"firstname" : "John"
}
}
}
J'espère que ça va aider :)
C'est assez facile, téléchargez et ajoutez à votre bibliothèque: https://code.google.com/p/google-gson/
Gson gsonObj = new Gson();
String strJson = gsonObj.toJson(yourObject);
Je ne voulais aucune dépendance vis-à-vis de gson et je voulais retourner un json hiérarchique à partir d'un contrôleur Spring afin qu'une carte profonde me suffise.
Cela fonctionne pour moi, il suffit de passer en boucle toutes vos clés et de passer dans une carte vide.
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);
}
}
Utilisation de la bibliothèque Java lightbend config ( 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());
}
Regardez ceci https://github.com/nzakas/props2js . Vous pouvez l'utiliser manuellement ou en fork et l'utiliser dans votre projet.
il suffit d'utiliser le constructeur org.json.JSONObject
qui reçoit une carte (dont les propriétés sont étendues):
JSONObject jsonProps = new JSONObject(properties);
jsonProps.toString();
Si les propriétés ne sont pas déjà chargées, vous pouvez le faire depuis un fichier.
Properties properties= new Properties();
File file = new File("/path/to/test.properties");
FileInputStream fileInput = new FileInputStream(file);
properties.load(fileInput);
Si vous voulez faire l'inverse et lire une chaîne json dans un fichier prop, vous pouvez utiliser com.fasterxml.jackson.databind.ObjectMapper
:
HashMap<String,String> result = new ObjectMapper().readValue(jsonPropString, HashMap.class);
Properties props = new Properties();
props.putAll(result);
Vous pouvez essayer avec https://github.com/mikolajmitura/Java-properties-to-json
Vous pouvez générer Json à partir de:
exemple de code:
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"));
dépendance maven:
<dependency>
<groupId>pl.jalokim.propertiestojson</groupId>
<artifactId>Java-properties-to-json</artifactId>
<version>4.0</version>
</dependency>
dépendance requise Java 7.
plus d'exemples d'utilisation sur https://github.com/mikolajmitura/Java-properties-to-json
Un peu de récursivité et Gson :)
public void run() throws IOException {
Properties properties = ...;
Map<String, Object> map = new TreeMap<>();
for (Object key : properties.keySet()) {
List<String> keyList = Arrays.asList(((String) key).split("\\."));
Map<String, Object> valueMap = createTree(keyList, map);
String value = properties.getProperty((String) key);
value = StringEscapeUtils.unescapeHtml(value);
valueMap.put(keyList.get(keyList.size() - 1), value);
}
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(map);
System.out.println("Ready, converts " + properties.size() + " entries.");
}
@SuppressWarnings("unchecked")
private Map<String, Object> createTree(List<String> keys, Map<String, Object> map) {
Map<String, Object> valueMap = (Map<String, Object>) map.get(keys.get(0));
if (valueMap == null) {
valueMap = new HashMap<String, Object>();
}
map.put(keys.get(0), valueMap);
Map<String, Object> out = valueMap;
if (keys.size() > 2) {
out = createTree(keys.subList(1, keys.size()), valueMap);
}
return out;
}