Java unterminated object error when making JSON - java

I'm trying to create a JSON object that looks like:
{
"values": {
"barcode": "{"title":"611269991000grant"}"
}
}
Note that the value of barcode is only a string. Here's what I'm writing:
// title = 611269991000grant
params = new JSONObject("{\"values\": {\"barcode\":" + "\"{\"title\":\"" + title + "\"}\" } }");
The problem however is that this will throw an exception saying
Unterminated object at character 26 of {"values": {"barcode":"{"title":"611269991000grant"}" } }
Anyone know what i'm doing wrong?

That's invalid JSON. Change
params = new JSONObject("{\"values\": {\"barcode\":" + "\"{\"title\":\"" + title + "\"}\" } }");
to
params = new JSONObject("{\"values\": {\"barcode\":" + "{\"title\":\"" + title + "\"} } }");
So that your JSON would finally be:
{
"values": {
"barcode": {"title":"611269991000grant"}
}
}

If your intent is that the value of barcode is a String representation of a document, and not a document ,then
"{"title":"611269991000grant"}"
is not valid, you either scape the inner double quotes " with \ or you replace the inner double quotes " with single quotes '
{
"values": {
"barcode": "{'title':'611269991000grant'}"
}
}
or
{
"values": {
"barcode": "{\"title\":\"611269991000grant\"}"
}
}

Found a solution to my problem:
String jsonobj = "{\\\"title\\\":\\\"" + title + "\\\"}";
params = new JSONObject("{\"values\": {\"barcode\":\"" + jsonobj + "\"} }");
I needed to double escape because the value of barcode is sent over a stream and I still needed it to be in JSON format. So my program now reads the JSON object as
{"values":{"barcode":"{\"title\":\"611269991000,grant\"}"}}
and the barcode value is sent to the stream and read by the webapp as
{"title":"611269991000,grant"}
pseudo JSON! I forgot to mention that the barcode value can only contain a string, which is why I was trying to do magic.

Related

How to convert csv to json with arrays

I have a csv file with an initial data for my app.
{
"id": 1,
"topic": "Архитектура",
"question": "Как называется буддийское архитектурное культовое сооружение?",
"rightanswer": "Ступа",
"wronganswer1": "Баба",
"wronganswer2": "Яга",
"wronganswer3": "Метла",
"passed": false,
"right": false
},
I need to parse it to json with the array of "answers", what options i have ?
Result should be like that :
{
"id": 1,
"topic": "Архитектура",
"question": "Как называется буддийское архитектурное культовое сооружение?",
"answers":[
"Ступа",
"Баба",
"Яга",
"Метла" ],
"passed": false,
"right": false
}
You are almost in the right direction but you have to use JSONArray for answers rather then adding them directly into the object with the name.
you can have an if where you will check if key contains the answer string then you can add into the JSONArray else add that key and value into JSONObject and add this JSONArray with the key answers into the main object once you done by adding all field.
This logic will keep your logic flexible.
it will help you to achieve your desire JSON.
EDIT: I would suggest you change your excel structure if you can. you should have all possible options in a single column (such as opt1,opt2,opt3,opt4) and correct answers in another column to gain simplicity and flexibility in your excel designa nd code.
I'm using gson
String str = "{\r\n" +
" \"id\": 1,\r\n" +
" \"topic\": \"Архитектура\",\r\n" +
" \"question\": \"Как называется буддийское архитектурное культовое сооружение?\",\r\n" +
" \"rightanswer\": \"Ступа\",\r\n" +
" \"wronganswer1\": \"Баба\",\r\n" +
" \"wronganswer2\": \"Яга\",\r\n" +
" \"wronganswer3\": \"Метла\",\r\n" +
" \"passed\": false,\r\n" +
" \"right\": false\r\n" +
" }"; //<== your json input
JsonParser parser = new JsonParser();
JsonObject input = parser.parse(str).getAsJsonObject(); //parser you Json to object
JsonObject output = new JsonObject();//my new jsonOutput
output.add("id", input.get("id"));
//other field .....
//the trick start here
JsonArray answer = new JsonArray();
answer.add(input.get("rightanswer"));
answer.add(input.get("wronganswer1"));
answer.add(input.get("wronganswer2"));
answer.add(input.get("wronganswer3"));
output.add("answers", answer);
System.out.println(output.toString());
result
{"id":1,"answers":["Ступа","Баба","Яга","Метла"]} // to lazy to parse other field sorry
Hope it helps

How to Post Json Data In Servlet?

I have a json data which can be something like:
1st json data
[
{
"id_form_delegate": "1",
"nama_merchant": "MATAHARI BARU SERASI",
"kota_merchant": "BALI",
"alamat_merchant": "JL PAKUBUWONO 2D",
"province_merchant": "BALI",
"mid_merchant": [
"112000902755",
"112000902754"
],
"tid_merchant": [
"2431002547",
"2531016215"
]
}
]
or something like
2nd json data
[
{
"id_form_delegate": "1",
"nama_merchant": "MATAHARI BARU SERASI",
"kota_merchant": "BALI",
"alamat_merchant": "JL PAKUBUWONO 2D",
"province_merchant": "BALI",
"mid_merchant": "112000902755",
"tid_merchant": "2431002547"
}
]
This my servlet code
JSONArray arrMid = jsonObject.getJSONArray("mid_merchant");
mid = new String[arrMid.size()];
JSONArray arrTid = jsonObject.getJSONArray("tid_merchant");
tid = new String[arrTid.size()];
//
System.out.println("nama_merchant: " + nama_merchant);
System.out.println("kota_merchant: " + kota_merchant);
System.out.println("alamat_merchant: " + alamat_merchant);
System.out.println("province_merchant: " + province_merchant);
System.out.println("mid: " + mid.length);
System.out.println("tid: " + tid.length);
if post 1st data result success, but if I post 2nd data I've Got error
this my error logs
net.sf.json.JSONException: JSONObject["mid_merchant"] is not a
JSONArray. net.sf.json.JSONException: JSONObject["tid_merchant"] is
not a JSONArray.
how to get value mid_merchant.length & tid_merchant.length using JSONArray
Thanks
The problem is that mid_merchant isn't an array in the second case, so you can't use JSONArray to get it's length because it has no length, it's just a String. You could send an array with only one value:
"mid_merchant": ["112000902755"],
or, if that's not what you want, you can check if it is an array (or even capture that exception) and get the String value with the getString method if it's not an array:
String stringMid = jsonObject.getString("mid_merchant");
You can use method get(String field) and check type of result:
Object node = jsonObject.get("mid_merchant");
String[] mid;
if (node instanceof JSONArray) {
mid = new String[((JSONArray) node).size()];
} else {
mid = new String[1];
}
or one-liner:
String[] mid = new String[node instanceof JSONArray ? ((JSONArray) node).size() : 1];
Try the following code
JSONArray arrMid=json.getJSONArray("mid_merchant");
String mid=arrMid.getJSONOBJECT.getJSONObject(0).getString("mid_merchant");
JSONArray tidMid=json.getJSONArray("tid_merchant");
String mid=tidMid.getJSONOBJECT.getJSONObject(0).getString("tid_merchant");

json not valid, quote and backslash

I been trying to solve this issue for quite a while now but i don't seem to have anymore route to take.
I had some backslash that i managed to remove with replace("\", "") but i still have some Quotation Mark like this one ---> " just in the beginning of my map and I don't have any idea how it gets there.
Here is my code:
public void actionPerformed(ActionEvent e) {
JsonObject obj = new JsonObject();
JsonArray ingredList = new JsonArray();
Map<String, String> ingredientAsMap = new HashMap<>();
JsonArray prepTime = new JsonArray();
Map<String, String> prepTimeAsMap = new HashMap<>();
JsonArray cookTime = new JsonArray();
Map<String, String> cookTimeAsMap = new HashMap<>();
obj.addProperty("Recipe Name", textField1.getText().toString());
for (int r = 0; r < model.getRowCount(); r++) {
ingredientAsMap.put("Ingredient", model.getValueAt(r, 0).toString());
ingredientAsMap.put("Measure", model.getValueAt(r, 1).toString());
ingredientAsMap.put("Quantity", model.getValueAt(r, 2).toString());
ingredList.add(String.valueOf(ingredientAsMap));
}
obj.addProperty("Ingredients Lists", String.valueOf(ingredList));
obj.addProperty("Preparation", editorPane1.getText().toString());
prepTimeAsMap.put("Hours", spinner3.getValue().toString());
prepTimeAsMap.put("Mins", spinner2.getValue().toString());
prepTime.add(String.valueOf(prepTimeAsMap));
obj.addProperty("Preparation Time", String.valueOf(prepTime));
cookTimeAsMap.put("Hours", spinner1.getValue().toString());
cookTimeAsMap.put("Mins", spinner4.getValue().toString());
cookTime.add(String.valueOf(cookTimeAsMap));
obj.addProperty("Cooking Time", String.valueOf(cookTime));
Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
String json = gson.toJson(obj).replace("\\", "");
try{
FileWriter writer = new FileWriter(System.getProperty("user.dir") + "\\" + textField1.getText().toString() + ".json");
BufferedWriter bw = new BufferedWriter(writer);
bw.write(json);
bw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println(json);
//System.out.println(System.getProperty("user.dir") + "\\" + textField1.getText().toString() + ".json");
}
Here is the output I get when my form is filled:
{
"Recipe Name": "Test",
"Ingredients Lists": "["{Ingredient=Ingredient0, Measure=ml, Quantity=0}","{Ingredient=Ingredient1, Measure=ml, Quantity=0}"]",
"Preparation": "This is a test.",
"Preparation Time": "["{Hours=0, Mins=0}"]",
"Cooking Time": "["{Hours=0, Mins=0}"]"
}
Notice the " before the [ in Ingredient List, Preparation Time and Cooking Time. How do I get rid of them?
Thanks in advance!
Your issue starts with lines like these
obj.addProperty("Ingredients Lists", String.valueOf(ingredList));
obj.addProperty("Preparation Time", String.valueOf(prepTime));
For the HashMaps, refer How to convert hashmap to JSON object in Java (not the accepted one, but the Gson answer)
Similarly, for the JSONArray, you don't need to String.value them. Just add directly. From the API, use the add(String name, JsonElement element) method.
obj.add("Preparation Time", prepTime);
Detailed answer
Stop string replacing. Your internal data sets are just not JSON, so you are building that JSON incorrectly.
Notice the syntax highlighting
Invalid
{ "Preparation Time": "["{Hours=0, Mins=0}"]" }
Valid - The inner string is escaped.
{ "Preparation Time": "[\"{Hours=0, Mins=0}\"]" }
Which is essentially seen as this to any JSON parser
{ "Preparation Time": "..." }
You can getString("Preparation Time"), and it returns "[\"{Hours=0, Mins=0}\"]" as a String. If you convert that to a JSONArray, then it's an array of strings. Print the first element, you should only see "{Hours=0, Mins=0}" (quotes are kept), and so you should be replacing the quotes and {} characters, not the backslashes. And you could split on equal signs to get key-values, and etc,etc... but that sounds like a lot of work.
Basically, there are no equal signs in key-value JSON pairs.
{Ingredient=Ingredient0, Measure=ml, Quantity=0}
So, Gson is doing to treat every single one of those keys's values as String type and any quotes or backslashes are going to be unescaped when you print the data, but it is stored in memory escaped.
However you want to parse the extra data is unrelated to JSON parsing, so that is my hint and you can stop scratching your head hopefully.
For what it's worth, here is JSON for that data. So, my suggestion is to fix the model class and pieces of code that generate this data.
{
"Recipe Name": "Test",
"Ingredients Lists": [{
"Ingredient": "Ingredient0",
"Measure": "ml",
"Quantity": 0
}, {
"Ingredient": "Ingredient1",
"Measure": "ml",
"Quantity": 0
}],
"Preparation": "This is a test.",
"Preparation Time": [{
"Hours": 0,
"Mins": 0
}],
"Cooking Time": [{
"Hours": 0,
"Mins": 0
}]
}

Parsing JSON Data (Android)

Alright. I have a JSON Object sent to me from a server which contains the following data:
{
"result":
[
{"status":"green","type":"data1"},
{"status":"green","type":"data2"},
{"status":"green","type":"data3"}
],
"status":"ok"
}
The data I want to get is the status for the three status values. Data1, data2, and data3 always show up in that order, so I'm now trying to grab the data by index (e.g. data1 = index 0, data2 = index 1, data3 = index 2). How do I do that?
Try following:
String stat1;
String stat2;
String stat3;
JSONObject ret; //contains the original response
//Parse to get the value
try {
stat1 = ret.getJSONArray("results").getJSONObject(0).getString("status");
stat2 = ret.getJSONArray("results").getJSONObject(1).getString("status");
stat3 = ret.getJSONArray("results").getJSONObject(2).getString("status");
} catch (JSONException e1) {
e1.printStackTrace();
}
You would use JSONObject and JSONArray, the entire string is one JSONObject so you would construct one with it.
JSONObject object = new JSONObject(YOUR_STRING_OF_JSON);
Then you can access it with different get methods depending upon your expected type.
JSONArray results = object.getJSONArray("result"); // This is the node name.
String status = object.getString("status");
for (int i = 0; i < results.length(); i++) {
String resultStatus = results.getJSONObject(i).getString("status");
String type = results.getJSONObject(i).getString("type");
Log.w("JSON Result #" + i, "Status: " + resultStatus + " Type: " + type);
}
You need to surround it with a try/catch because JSON access can throw a JSONException.
Try re-factoring via a forEach loop
var testData =
{
"result":
[
{"status":"green","type":"data1"},
{"status":"green","type":"data2"},
{"status":"green","type":"data3"}
],
"status":"ok"
};
var output = new Object;
var resultSet = new Object;
resultSet = testData.result;
resultSet.forEach(function(data)
{
theStatus = data['status'];
theType = data['type']
output[theType] = theStatus;
});
console.log( output['data1'] );
If you've got your models setup to mirror that data set, then you can let GSON (https://code.google.com/p/google-gson/) do a lot of your work for you.
If you want a bit more control, and want to parse the set yourself you can use JSONObject, JSONArray. There's an example of parsing and assembling a json string here: Android create a JSON array of JSON Objects

Passing a JavaScript object using addJavascriptInterface() on Android

Is it possible to pass a JavaScript object from JavaScript to Java using addJavascriptInterface()? Something along these lines:
var javaScriptObject = {"field1":"string1", "field2":"string2"};
JavaScriptInterface.passObject(javaScriptObject);
How would such a call be captured on the Java side? I have no problem setting up the interface to send a string, but when I send an object, I receive null on the Java end.
AFAIK, addJavascriptInterface() only works with primitive types and Strings, and so you cannot pass arbitrary Javascript objects.
This is how I am doing...
In Android...
#JavascriptInterface
public void getJSONTData(String jsonData) {
try {
JSONObject data = new JSONObject(jsonData); //Convert from string to object, can also use JSONArray
} catch (Exception ex) {}
}
In JavaScript...
var obj = { Name : 'Tejasvi', Age: 100};
var str = JSON.stringify(obj);
Android.getJSONTData(str);
As of now, I could not find any other proper way to pass the native JavaScript object directly to JavascriptInterface.
Calling Android.getJSONTData({ Name : 'Tejasvi', Age: 100}) results in null (if parameter type is Object) or undefined (if parameter type is defined as String) in getJSONTData.
I found a solution, using JSON. My Java method returns a JSONArray, on my javascript code I receive this and convert to a javascript vector using JSON.parse(). See the example:
Java:
public class JavaScriptInterface {
Context mContext;
private static int ind=-1;
private static int [] val = { 25, 25, 50, 30, 40, 30, 30, 5, 9 };
public JavaScriptInterface(Context c) {
mContext = c;
}
#JavascriptInterface
public JSONArray getChartData() {
String texto = " [ {name: 'valor1', 2007: "+val[(++ind)%9]+"}, "+
" {name: 'valor2', 2007: "+val[(++ind)%9]+"}, "+
" {name: 'valor3', 2007: "+val[(++ind)%9]+"} ]";
JSONArray jsonar=null;
try {
jsonar = new JSONArray(texto);
} catch (JSONException e) {
e.printStackTrace();
}
return jsonar;
}
}
Now the javascript code:
window.generateData = function() {
/*var data = [ {name: 'valor1', 2007: 50},
{name: 'valor2', 2007: 20},
{name: 'valor3', 2007: 30} ]; */
var data = JSON.parse( Android.getChartData() );
return data;
};
The commented code above show how it was when static, and now the data came from the Java code.
It was testes on Android 2.1 and 3.2.
I can run this feature
In Javascript :
var data = {
'username' : $('#username').val().trim(),
'password' : $('#password').val().trim(),
'dns' : $('#dns').val().trim()
}
var str = JSON.stringify(data);
Native.getLoginService(str);
In Android :
#JavascriptInterface
public void getLoginService(String jsonData){
try{
JSONObject data = new JSONObject(jsonData);
String username = data.getString("username");
String password = data.getString("password");
String dns = data.getString("dns");
Log.i("TAG",username + " - " + password + " - " + dns);
}catch (Exception ex){
Log.i("TAG","error : " + ex);
}
}
Good luck with...
I think you can also pass JSONObject and JSONArray. So not only primitive types, but also primitive types stored in a javascript array [0,1,2] or dictionary {one:1, two:2}.
I have NOT verified this in code, just read the docs. Might be using it soon.
You can't pass JSONObject or JSONArray, but you can send strings with that form and parse them to those types.
Your option is to expose the method using strings and then you can use the JSONObject or JSONArray to parse the string and use it accordingly.
Here is what I did.
#JavascriptInterface
public void passJSON(String array, String jsonObj) throws JSONException
{
JSONArray myArray = new JSONArray(array);
JSONObject myObj = new JSONObject(jsonObj);
...
}
where array is '["string1","string2"]' and jsonObj is '{attr:1, attr2:"myName"}'

Categories

Resources