Java replace (remove) substrings in response (before returning to app)

I have this string (yes, it is a string built by StringBuilder()) being returned from my web call:

responseContent = {"KEYS":["appId:projectId:key1","appId:projectId:key2","appId:projectId:key3"]}

Before returning this output to the app, I would like to strip:

appId:projectId:

from each of the elements, and then return this to the app:

responseContent = {"KEYS":["key1","key2","key3"]}

I have found that if I manually escape the " with \" then a replace() will work, but this doesn't work if I try to do this programmatically:

responseContent.replace("\"","\\\"");
responseContent.replace(appId + ":" + projectId + ":","");

Can anyone provide a pointer as to where I am going wrong, or what I can do to fix this? This needs to be done in the code, not in the app, so that the user/developer is presented with clean keys.
(note: appId and projectId are just placeholders)
I have also tried with replaceAll(), but only as above.

SO: regex - Java string how to replace " with \" to escape JSON? - Stack Overflow

Proof that it works with manually entered escapes:

image

I don't see why the extra replacement of "\"" to "\\\"" is necessary. If the string already contains valid JSON then this will actually make it become invalid JSON. As you've demonstrated in your screenshots, the replace method does the right thing without having to do any substitution on the double quote character.

Yes, but I had to put those backslashes in there, I can't do that for every call :slight_smile:

In Java string literals you have to escape the double quotes otherwise they would be interpreted as the end of the string. They're not actually escaped in the content of the string, it's solely for the purpose of communicating with the tokenizer.

1 Like

and that is what appears to be happening.

Can I do something to my JSON string, convert to object, then strip each object element?

As this is fairly trivial to do with blocks, can you please point me to the sources java for dictionaries and lists, and I will see if I can figure it out from there. :slight_smile:

YailList and YailDictionary

Taifun

1 Like

Thanks @ Taifun ( actually needed the web component java for the JSON with dictionaries :upside_down_face: )

Now to code this:

So you want to convert a JSON string to dictionaries?

I have an open source extension that might help you. It was originally for only Kodular, because the Web component in Kodular does not have JsonTextDecodeWithDictionaries, but you can look at the source code.

There are some useful methods on JsonUtil class for converting Json String to YAIL object.

1 Like

Thank you both.

I believe I have got this part:

with (something like):

Object rcJson = JsonUtil.getObjectFromJson(responseContent, true);

Extracting the array from the Json Object is next

image

which I believe is here ?

I think so.

Does this help you?

OK, making progress. These two lines return the array

JSONObject rcJson  = new JSONObject(responseContent);
String rcArray = rcJson.getString("KEYS");
["appId:projectId:key1","appId:projectId:key2","appId:projectId:key3"]

but this

String repPart = "appId:projectId:";
rcArray.replace(repPart,"");

is not having any effect ?

If JSON is same format as you mentioned on the first post then it is way much easier to get array using org.json's classes. You don't need to add any dependency on your extension for this as AppInventor already uses org.json classes(or maybe Android Sdk already have org.json)

[EDIT : You already posted about this before me while i was writing code here :sweat_smile:]

/*
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
*/
public String getKeys(String jsonString){
   try {
            JSONObject jsonObject = new JSONObject(jsonString);
            return jsonObject.getJSONArray("KEYS").toString();
        } catch (JSONException exception){
            // throw an exception 
            return "";
        }
}
public YailList getLists(String responseContent) {
        // Use try catch too.. 
        JSONObject rcJson = new JSONObject(responseContent);
        JSONArray rcArray = rcJson.getJSONArray("KEYS");
        ArrayList <String> arrList = new ArrayList <> ();
        for (int i = 0; i < rcArray.length(); ++i) {
            arrList.add((String.valueOf(rcArray.get(i))).replace("appId:projectId:", ""));
        }
        return YailList.makeList(arrList);
    }

I edited this here and haven't tried the code yet.

1 Like

If "KEYS" points to an array like in your first post, getString will return a copy as a string. What you want to do is something more like:

JSONObject data = new JSONObject(responseContent);
JSONArray keys = data.getJSONArray("KEYS");
for (int i = 0; i < keys.length(); i++) {
  keys.put(i, keys.getString(i).replace("app:projectId:", ""));
}
String transformedContent = data.toString();
// ... use transformed content ...
1 Like

@ewpatton

That looks like what was trying to get to :slight_smile:

I shall report back

OK using that sequence it returns:

{"KEYS":["key1","key2","key3"]}

which is just what I wanted. Many thanks :slight_smile:

1 Like

I thought you need keys in list so have suggested this.
I just see what you need :sweat_smile:

It is a better solution in many ways :+1:, so thank you for your work :slight_smile: , but Evan's approach returns the data in a format that matches other returns I get from what I am up to :wink:

1 Like