How to create hierarchical JSON from java.util.Properties object - java

I'm looking for good way or complete API to create a hierarchical JSON from plain java.util.Properties object.
Exist java.util.Properties object, e.g.:
car.color=blue
car.places=4
car.motor.dimension=2L
car.motor.ps=120
and the target json structur should be:
{
"car":
{"color":"blue",
"places":4,
"motor":
{"dimension":"2L",
"ps":120
}
}
}

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;
}

The following project 'Java Properties to JSON' achieves exactly what you seek.
However, it has a restriction on Java 8.
Would be great if someone actually provides changes to make it Java 7 compatible.

You will need to parse your properties to Map<String, Object> where your Object will be either another Map<String, Object> or a String. For this you will have to write your own code. I suppose you will need to take your properties keys and split them over "." using method String.split(). Note that in your code you will need to use "\\." as a parameter as "." is a regular expression. Once you build your Map it is very easy to convert it to JSON using Jackson library or any available JSON library.

Related

Convert Json string into Hashmap of hashmap in java

I am new to json processing, below is the json string our clients send us, I want to
read this json string into a hashmap of hasmap so that even for the "Client"/"params" key below
I can access its key and value set and process them .
var incomingMessage =
"{
\"dev1\":\"NULL\",
\"devkp2\":\"val\",
\"compression\":\"NULL\",
\"subcode\":\"P_CODE\",
\"code\":\"PEB_USER\",
\"Client\":{
\"first_name\":\"Perf FN 422677\",
\"client_last_name\":\"DP_PSL\",
\"clientid\":\"780A832\",
\"email\":\"DP_PS#airb.com\"
},
\"clientsrc\":\"dev.client.notvalid\",
\"params\":{
\"Name\":\"ABC_PR\",
\"client_ID\":\"PSL\",
\"domain\":\"airb.com\"
}
}"
This is my current code which works fine for non-nested json strings (that is without the Client.params key in above json string):
public static void convertJsonStringToMap(String incomingMessage) {
HashMap<Object, Object> map = new HashMap<Object, Object>();
JSONObject jObject = new JSONObject(incomingMessage);
Iterator<?> keys = jObject.keys();
while (keys.hasNext()) {
String key = (String) keys.next();
String value = jObject.getString(key);
map.put(key, value);
}
for (Map.Entry<Object, Object> entry : map.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
}
I want to be able to similarly read nested keys like Client and params. I am using jdk11. I am fine with using jackson or google gson, both approaches would work.
Please help me with processing these nested json string.
A valid JSON string can be easily converted to a Map using Jackson ObjectMapper.
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> parsedMap = mapper.readValue(incomingMessage, Map.class);
It works for nested elements as well -
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
String someJsonString = "{" +
"\"A\":\"1\"," +
"\"B\":2," +
"\"C\":" +
"{" +
"\"D\":\"4\"" +
"}" +
"}";
Map<String, Object> outputMap = mapper.readValue(someJsonString, Map.class);
System.out.println(outputMap);
}
Output:
{A=1, B=2, C={D=4}}

How to convert nested json into Map without typecasting using Gson

I am trying to understand/learn how to pull data from a weather API, i have successfully done that and i got a Json file filled with data. I managed with gson put the information into a Map.
But it also has nested json for key main were i'm pulling out value into what may by explicit typecasting.
The thing i would like to ask, is if there is a neater way of doing this and so that i don't need to do explicit type casting nested json into Map
Map<String, Object> resultMap = new Gson().fromJson(jsonString, new TypeToken<HashMap<String, Object>>() {
}.getType());
for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
System.out.println(entry);
}
System.out.println(resultMap.get("temp"));
Map<String, Object> mainMap = (Map<String, Object>) resultMap.get("main");
System.out.println("Temp: " + mainMap.get("temp"));
This is my output in the console:
rain={}
visibility=10000.0
timezone=7200.0
main={temp=8.1, pressure=1007.0, humidity=93.0, temp_min=7.0, temp_max=10.0}
clouds={all=75.0}
sys={type=1.0, id=1788.0, country=SE, sunrise=1.571203601E9, sunset=1.571240388E9}
dt=1.571249075E9
coord={lon=18.06, lat=59.33}
weather=[{id=301.0, main=Drizzle, description=drizzle, icon=09n}]
name=Stockholm
cod=200.0
id=2673730.0
base=stations
wind={speed=3.6, deg=40.0}
null
Temp: 8.1
I would say you can convert the json string into Map<String, JsonElement> so that you have so methods to find nested object is JsonObject or JsonArray. So in the blow example main is key with JsonObject as value
main: {
temp:8.1,
pressure:1007.0,
humidity=93.0,
temp_min=7.0,
temp_max=10.0
}
You can parse the value into Map by using fromJson
Map<String, Object> resultMap = new Gson().fromJson(jsonString, new TypeToken<Map<String, Object>>() {
}.getType());
for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
System.out.println(entry);
}
System.out.println(resultMap.get("temp"));
Map<String, Object> mainMap = new Gson().fromJson(resultMap.get("main").toString(), new TypeToken<Map<String, Object>>() {
}.getType());
System.out.println("Temp: " + mainMap.get("temp"));

Create a map from an Iterable<Map.Entry> in groovy

I need to fill map with Iterable<Map.Entry>. The following is an original java code:
Iterable<Map.Entry<String, String>> conf;
Iterator<Map.Entry<String, String>> itr = conf.iterator();
Map<String, String> map = new HashMap<String, String>();
while (itr.hasNext()) {
Entry<String, String> kv = itr.next();
map.put(kv.getKey(), kv.getValue());
}
I have to rewrite it in groovy. Is there a concise groovy-way to do it?
I'd use collectEntries for that. It's similar to collect, but it's purpose is to create a Map.
def sourceMap = ["key1": "value1", "key2": "value2"]
Iterable<Map.Entry<String, String>> conf = sourceMap.entrySet()
def map = conf.collectEntries {
[(it.key): it.value]
}
Note the round braces around it.key that allow you to use a variable reference as key of the newly generated Entry.
In Groovy you can use the each closure instead of Iterator as follows
Map<Map.Entry<String, String>> sourceMap = ["key1" : "value1", "key2" : "value2"]
Map<Map.Entry<String, String>> targetMap = [:]
sourceMap.each{ key, value ->
targetMap[key] = value
}
println ​targetMap
Working example here : https://groovyconsole.appspot.com/script/5100319096700928

How to parse JSON object into `Map<String, HashSet<String>>`

I'd like to parse this JSON object:
"{
\"Rao\":[\"Q7293658\",\"\",\"Q7293657\",\"Q12953055\",\"Q3531237\",\"Q4178159\",\"Q1138810\",\"Q579515\",\"Q3365064\",\"Q7293664\",\"Q1133815\"],
\"Hani Durzy\":[\"\"],
\"Louise\":[\"\",\"Q1660645\",\"Q130413\",\"Q3215140\",\"Q152779\",\"Q233203\",\"Q7871343\",\"Q232402\",\"Q82547\",\"Q286488\",\"Q156723\",\"Q3263649\",\"Q456386\",\"Q233192\",\"Q14714149\",\"Q12125864\",\"Q57669\",\"Q168667\",\"Q141410\",\"Q166028\"],
\"Reyna\":[\"Q7573462\",\"Q2892895\",\"Q363257\",\"Q151944\",\"Q3740321\",\"Q2857439\",\"Q1453358\",\"Q7319529\",\"Q733716\",\"Q16151941\",\"Q7159448\",\"Q5484172\",\"Q6074271\",\"Q1753185\",\"Q7319532\",\"Q5171205\",\"Q3183869\",\"Q1818527\",\"Q251862\",\"Q3840414\",\"Q5271282\",\"Q5606181\"]
}"
and with that data generate a Map<String, HashSet<String>>.
Essentially I want to reverse this procedure.
All the code for this project can be found on my github page here, it's quite short.
update
File f = new File("/home/matthias/Workbench/SUTD/nytimes_corpus/wdtk-parent/wdtk-examples/JSON_Output/user.json");
String jsonTxt = null;
if (f.exists())
{
InputStream is = new FileInputStream("/home/matthias/Workbench/SUTD/nytimes_corpus/wdtk-parent/wdtk-examples/JSON_Output/user.json");
jsonTxt = IOUtils.toString(is);
}
//System.out.println(jsonTxt);
Gson gson=new Gson();
Map<String, HashSet<String>> map = new HashMap<String, HashSet<String>>();
map=(Map<String, HashSet<String>>) gson.fromJson(jsonTxt, map.getClass());
//// \\ // ! PRINT IT ! // \\ // \\ // \\ // \\ // \\ // \\
for (Map.Entry<String, HashSet<String>> entry : map.entrySet())
{
System.out.println(entry.getKey()+" : " + Arrays.deepToString(map.entrySet().toArray()) );
}
Using Gson
Gson gson = new Gson();
String json = "<YOUR_JSON_STRING_HERE>";
Map<String, HashSet<String>> map = new HashMap<String, HashSet<String>>();
map = (Map<String, HashSet<String>>) gson.fromJson(json, map.getClass());
Update:
Use TypeToken
Type type = new TypeToken<Map<String, HashSet<String>>>(){}.getType();
map = (Map<String, HashSet<String>>) gson.fromJson(json, type);
Or you could parse it...
Create an object of JSONObject
Create an object of HashMap
Iterate over jsonObj.keys() and for every key get value like
jsonObj.getString(key).
Put it in the map like map.put(key, value).

How to set atributes throught reflexion

I have map of <String, Object>:
params={
dateOfBirthTo=23.05.2013,
lastName=bbb, ssn=aa-ccc-ddd,
gender=MALE,
dateOfBirthFrom=03.05.2013,
firstName=aaa
}
Then I have form which contains variable from this map. How I can create new form with this value through reflection?
Something like:
SimpleForm form = new SimpleForm();
Map<String, Object> parameters = request.getParams();
for (Map.Entry<String, Object> entry : parameters.entrySet()) {
// fill form
}
You could use Apache Commons BeanUtils
SimpleForm form = new SimpleForm();
Map<String, Object> parameters = request.getParams();
for (Map.Entry<String, Object> entry : parameters.entrySet()) {
BeanUtils.setProperty(form, entry.getKey(), entry.getValue());
}

Categories