What's the best way to return a Java Map using the JSON format?
My specific need is a key -> value association between a date and a number.
My concern is this: My structure basically contains N elements of the same type (a mapping between a date and a number), and I want to be able to quickly iterate through them in Javascript.
In XML, I would have:
<relation date='mydate' number='mynumber'/>
<relation date='mydate' number='mynumber'/>
...
<relation date='mydate' number='mynumber'/>
and I would use jQuery like this:
$(xml).find("relation").each(function() {
$(this).attr("date"); // the date
$(this).attr("number"); // the number
})
It's my first experience with JSON and I would like to know if I can do something similar.
Although I haven't tried it myself, the JSONObject of the Java implementation of JSON from json.org has a JSONObject(Map) constructor.
Once a JSON object is created from the Map, then a JSON string can be obtained by calling the toString method.
String myJson = "{ ";
for (String key : myMap.keySet())
myJson += key + " : " + "'" + myMap.get(key) + "',";
myJson += " } ";
I leave the last comma because it wont give us many problems. The javascript just ignores it.
Well, this respond your question but I guess that won't help much. Try posting a more specific one.
Related
I have this String
String tst = " {"id":$.id, "parent_id":200}";
I am trying to extract $.id from this string and replace it by an other word.
For now I tried:
tst = tst.replaceAll("(\\$.).", "other_word");
But this code is replacing all the rest (like "parent_id"...) by this other word
here is the output:
{"id":other_wordd_mag, "parent_id":200}
it's replacing only the "i" from "id_mag" any solution ?
This code seems to be replacing as expected:
String tst = " {\"id\":$.id, \"parent_id\":200}";
System.out.println(tst.replaceAll("\\$\\.id", "other_word"));
Output:
{"id":other_word, "parent_id":200}
Update
If you need to substitute some variables inside JSON, you can use the following regexp:
String tst = "{\"id\":$.id, \"name\":$.name, \"parent_id\":200}";
System.out.println(tst.replaceAll("(\\$\\.\\w+)", "\"other_word\"")); // using shorthand for word characters
output:
{"id":"other_word", "name":"other_word", "parent_id":200}
Or, if you have a map of variables in the form of key-value pairs, you can use this method:
static String replaceVars(String src, Map<String, String> vars) {
for (Map.Entry<String, String> e : vars.entrySet()) {
src = src.replaceAll("(\\$\\." + e.getKey()+ ")", "\"" + e.getValue()+"\"");
}
return src;
}
// -----------
String tstDiff = "{\"id\":$.id, \"name\":$.name, \"parent_id\":200}";
System.out.println(replaceVars(tstDiff, Map.of("id", "my_id", "name", "my_name")));
output:
{"id":"my_id", "name":"my_name", "parent_id":200}
Working with these types of strings can be a little bit easier if you know what JSON is.
And Java has also a really good library for handling Json strings called GSON.
You can use this library and for this specific case use the fromJson method.
But if you want to work with regex and get familiar with Strings:
tst.replaceAll("\\$\\.id", "other_word")
This should work properly.
I'm trying to find a nice solution to a movie filtering system built in java and with a mysql database. The user is supposed to be able to filter which movies they wish to see based on a number of attributes, such as: director, actor, length, genre, year,...,. In total there are 11 fields which can be used to filter the query.
The problem is some of these fields can (and probably will) be left blank. For instance, maybe the user only wants to filter data based on a certain genre, director and length. Or maybe they only want to filter it based on the prodution studio, and dont care about the other filter options.
I have made a connection to the server, and the problem is in creating the "SQL_String" that I will use in statement.executeQuery(SQL_String).
Lets say I only wanted to filter for one field. Then I know I could write
String field = //user input (for example: actor)
String filter = //user input (for example: 'tom cruise')
String SQL_String = "SELECT * FROM Movies WHERE "+field + "=" +filter
But if i want to allow the user to filter based on several (or zero) fields, then I dont know how to write the code.
Some example queries could be:
"SELECT * FROM Movies WHERE (director = 'steven spielberg' AND genre = 'action' AND length >100)"
"SELECT * FROM Movies WHERE (type = 'tv-series' AND actor = 'bob odenkirk')"
So the user can specify which fields they want to filter (if any) and i need to come up with a java code that can take those into account and construct a query string.
Since you don't know how many fields the user will filter on but you do know that the data you're dealing with has two parts (the field and the filter), the first two things that come to my mind are maps and tuples. Since, unlike Python, Java does not have a built in tuple data type (to my knowledge), here is a small example solution that I thought of for your problem solved using Java's HashMap and Map classes.
In this example, I create a HashMap with the key being a string for the "field" and the value being a string for the "filter". You can set these values based on the user input wherever you have that in your code (in this example, simply hard-coded in the main method). Then you can loop through the key-value pairs in your HashMap (see this helpful post), appending the key and value as well as the additional characters necessary for the query. This is a simple example but shows a possible solution route.
If you want to make sure that this solution works for the cases where you filter value is an integer, then just add in another if-statement in the loop to try parsing for an integer and if one exists to not add the extra \' escape characters.
import java.util.HashMap;
import java.util.Map;
public class MovieQueryTest {
public static void main(String[] args) {
String SQL_Query = "SELECT * FROM Movies WHERE ";
HashMap<String, String> queryFilters = new HashMap<>();
queryFilters.put("director", "Steven Spielberg");
queryFilters.put("type", "tv-series");
queryFilters.put("actor", "Bob Odenkirk");
boolean firstQueryFilter = true;
for (Map.Entry<String, String> entry : queryFilters.entrySet()) {
if (firstQueryFilter) {
SQL_Query += entry.getKey() + "=\'" + entry.getValue() + "\'";
firstQueryFilter = false;
} else {
SQL_Query += " AND " + entry.getKey() + "=\'" + entry.getValue() + "\'";
}
}
System.out.println(SQL_Query);
}
}
I have a ConcurrentSkipListMap which stores sorted data based on the timestamp since epoch. Now using Servlets I want to return this data to the browser. But, when I convert the Java map into JSON the order is lost(I know JSON doesn't maintain it). I have also tried to return a string to the user which I create while iterating the map
returnString = "{";
for (Map.Entry<Long, String> entry : mapname.entrySet()) {
returnString += "\"" + String.valueOf(entry.getKey()) + "\":" + "\"" + entry.getValue() + "\",";
}
returnString += "}";
This String with escape sequences works untill my getValue() is a String. If it turns out to be a JSON Object, Javascript is unable to parse the entire object because the escape sequences are missing for that value.
I want to return to the browser a format which is easily readable in JavaScript and which will not require me to sort in JavaScript as my Map in Java is already sorted.
Is this possible? How?
PS: I may be missing something obvious because I've had my head into this for hours.
Try the GSON library. It will help you
GsonBuilder builder = new GsonBuilder();
builder.setPrettyPrinting();
builder.serializeNulls();
Gson gsonExt = builder.create();
String serialize = gsonExt.toJson(mapname);
I am new to JSON and getting confused everytime I create a new one.
I am trying to create a JSON array like this :
{
"id":"2003",
"HouseMD" :
{
"Doctor_1": "Thirteen",
"Doctor_2" : "Chase"
"Doctor_n" : "Someone"
}
}
Basically I am trying to add info dynamically from Doctor_1 to Doctor_n" in a for loop. and if I use a JSON Object I am only getting the last value when I finally print it.
How do I get something that I want?
Any help appreciated.
Thanks.
JSON arrays look like this:
{ "id":"2003", "HouseMD" : [{ "Doctor_1": "Thirteen"}, {"Doctor_2" : "Chase"}, {"Doctor_n" : "Someone" }]}
Notice the square bracket that surrounds each JSON object in the array.
Here is the link to the JSON website, which can offer more info:
JSON
Note that in order for the code below to work, you will also need the JSON library, which you can easily download from here Download Java JSON Library
I don't know the approach you are using, but based on the format you want, I would do something like this:
JSONObject data = new JSONObject();
data.put("id", "2003");
JSONObject doctors = new JSONObject();
//here I suppose you have all doctors in a list named doctorList
//and also suppose that you get the name of a doctor by the getName() method
for (int i = 0; i < doctorList.size(); ++i)
{
doctors.put("Doctor_" + (i+1), doctorList.get(i).getName();
}
data.put("HouseMD", doctors);
//then you could write to a file, or on screen just for test
System.out.println(data.toString());
However, I feel you need to become more comfortable with JSON, so try starting here.
I have this JSON file that is read and stored in a String called jsonString and it looks like this:
{
"position":1,
"team_id":10260,
"home":
{
"played":18,
},
},
{
"position":2,
"team_id":8456,
"home":
{
"played":12,
},
},
Code for parsing:
JSONObject obj = new JSONObject(jsonString);
Iterator it = obj.keys();
while(it.hasNext()){
String s = it.next().toString();
System.out.print(s + " " + obj.getString(s) + " ");
}
Output is: position 1 home {"played":18} team_id 10260
So it doesn't read the rest of the file. Can you tell me what is the problem? And also, why home {"played":18} is printed before team_id 10260?
If you look at the way your brackets are organized, you can see that your String actually contains several JSON objects, and the construction stops after the first complete one.
As for your second question, Iterators seldom have a guaranteed order, so you can't make any assumptions about which order the elements will be returned in.
The order will be dependent on the type of Map that JSONObject uses; could be indeterminate, or could be by the key's codepoint, or could be in order read, depending on, e.g. HashMap, TreeMap or LinkedHashMap.
Other than that, there are two objects serialized and JSONObject has apparently just stopped after the first one. You may need to wrap the entire input in a set of { }.