26

I am trying to get an array of objects from the server, using JSON.

The server sends me the following string.

"[{\"DealComment\":null,\"DealVotes\":[],\"DealId\":1,\"CompanyId\":1,\"StartDate\":\"2012-12-13T00:00:00\",\"EndDate\":\"2012-12-16T00:00:00\",\"CouponCode\":\"Test Coupon 1\",\"Description\":\"Test Deal Description 1\",\"VoteUp\":null,\"VoteDown\":null,\"ViewCount\":null,\"Title\":\"Test Deal 1\"},{\"DealComment\":null,\"DealVotes\":[],\"DealId\":2,\"CompanyId\":1,\"StartDate\":\"2012-12-16T00:00:00\",\"EndDate\":\"2012-12-17T00:00:00\",\"CouponCode\":\"Test Coupon 2\",\"Description\":\"Test Description 2\",\"VoteUp\":null,\"VoteDown\":null,\"ViewCount\":null,\"Title\":\"Test Deal 2\"},{\"DealComment\":null,\"DealVotes\":[],\"DealId\":3,\"CompanyId\":1,\"StartDate\":\"2012-12-14T00:00:00\",\"EndDate\":\"2012-12-15T00:00:00\",\"CouponCode\":\"Test Code 3\",\"Description\":\"Test Description 3\",\"VoteUp\":null,\"VoteDown\":null,\"ViewCount\":null,\"Title\":\"Test Deal 3\"},{\"DealComment\":null,\"DealVotes\":[],\"DealId\":4,\"CompanyId\":1,\"StartDate\":\"2012-12-12T00:00:00\",\"EndDate\":\"2012-12-13T00:00:00\",\"CouponCode\":\"Test Coupon 4\",\"Description\":\"Test Description 4\",\"VoteUp\":null,\"VoteDown\":null,\"ViewCount\":null,\"Title\":\"Test Deal 4\"},{\"DealComment\":null,\"DealVotes\":[],\"DealId\":5,\"CompanyId\":2,\"StartDate\":\"2012-12-12T00:00:00\",\"EndDate\":\"2012-12-14T00:00:00\",\"CouponCode\":\"AwD\",\"Description\":\"Very awesome deal!\",\"VoteUp\":null,\"VoteDown\":null,\"ViewCount\":null,\"Title\":\"Awesome Deal 1\"}]"

Now, if you look at the string closely, you would notice that it contains an \" instead of every ". The string cannot be formatted to a JSONArray right now. So, I need to replace every occurrence of \" with " , which would have a pretty easy task, had \ not been an escape sequence.

I tried using the following code.

String jsonFormattedString = jsonStr.replaceAll("\\", "");

But it gives me the following exception.

12-19 00:35:59.575: W/System.err(444): java.util.regex.PatternSyntaxException: Syntax error U_REGEX_BAD_ESCAPE_SEQUENCE near index 1:
12-19 00:35:59.575: W/System.err(444): \
12-19 00:35:59.575: W/System.err(444):  ^

My whole code, in case it is of any use :

public void getAllDealsFromServerJson()
{

    String apiUrl = "http://passme.azurewebsites.net/api/TestApi/";


    HttpClient client = new DefaultHttpClient();
    HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); //Timeout Limit
    HttpResponse response;
    JSONObject json = new JSONObject();

    try{
        HttpPost httpPost = new HttpPost(apiUrl);
        json.put("requestType", "getalldeals" );

        StringEntity se = new StringEntity( json.toString());  
        se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
        httpPost.setEntity(se);
        response = client.execute(httpPost);
        Log.d("Http Response:", response.toString());
        jsonResponse = response.toString();

        BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
        String jsonStr = reader.readLine();
        Log.d("String Response", jsonStr);
        String jsonFormattedString = jsonStr.replaceAll("\\", ""); // gives error
        Log.d("Formatted String", jsonFormattedString);
        //JSONTokener tokener = new JSONTokener(jsonFormattedString);
        /*JSONObject finalResult = new JSONObject(tokener);
        Log.d("JSON Response", "" + finalResult.optString("Title"));*/
        JSONArray resultArray = new JSONArray(jsonFormattedString);
        Log.d("JSON Array Result Length", "" + resultArray.length());
        Log.d("JSON Array Result ", "" + resultArray.getJSONObject(0).optInt("DealId"));

    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}
Wojciech Wirzbicki
  • 3,887
  • 6
  • 36
  • 59
Swayam
  • 16,294
  • 14
  • 64
  • 102

6 Answers6

47

Try this:

String jsonFormattedString = jsonStr.replaceAll("\\\\", "");

Because the backslash is the escaping character in a regular expression (replaceAll() receives one as parameter), it has to be escaped, too.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • 3
    `String jsonFormattedString = jsonStr.replace('\\', '');` is easier since you don't have double escape. Docs say: Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar. – mike jones Dec 18 '12 at 19:23
  • 1
    @mikejones If you notice from the question, that's what the OP was originally doing and it wasn't working. – Hunter McMillen Dec 18 '12 at 19:23
  • @swayam glad to hear that! please don't forget to accept this solution, if it was helpful for you :) – Óscar López Dec 18 '12 at 19:24
  • 3
    @HunterMcMillen: Not quite. The OP was using `replaceAll(String, String)`, whereas @mikejones was suggesting using `replace(char, char)`. (Unfortunately, @mikejones's solution wouldn't have worked either, since there is no "empty char" `''`.) – Louis Wasserman Dec 18 '12 at 19:26
  • 1
    @ÓscarLópez : It was more than helpful! It was awesome! And well, SO wants me to wait for another 6 minutes before I can hit the accept mark. So, I guess I am 6 minutes away from accepting it! :D – Swayam Dec 18 '12 at 19:27
  • 8
    This may solve the problem at hand, but it could cause problems down the road. Here we're assuming that the only use of backslashes is to prefix a double quote, and that may be true for _this_ example data. The root cause though is that the server is doubly JSON encoding the data. Without addressing that specifically, your code has a hidden bug that will only blow up when eventually the result has a genuine backslash which gets stripped accidentally. – jimbo Dec 18 '12 at 19:30
  • @ÓscarLópez , Could you please help me. Here is my JSON object {"checkpoint":"false","fname":"ekq1LbxBvCo=","livingArrangement":"","education":"","gender":"Male","mobileNumber":"9IG8RjfnTxlcvNXaMS8Rhg==","mailId":"CslHja5q40ssG12Cf55L\/w==","significantOther":"","age":"","maritalStatus":"Single","agreed":"false"} Acc. to your method, I am first converting into JSON string and then trying to replace "\". But this is not working for me. Could you suggest any other way remove "\" from mailId inside JSON object? – PyDevSRS Apr 20 '17 at 09:36
16

Actually the correct way would be:

String jsonFormattedString = jsonStr.replace("\\\"", "\"");

You want to replace only \" with ", not all \ with nothing (it would eat up your slashes in json strings, if you have ones). Contrary to popular believe replace(...) also replaces all occurrences of given string, just like replaceAll(...), it just doesn't use regexp so it usually be faster.

Krzysztof Krasoń
  • 26,515
  • 16
  • 89
  • 115
11

Just use:

try {
        jsonFormattedString = new JSONTokener(jsonString).nextValue().toString();
    } catch (JSONException e) {
        e.printStackTrace();
    }

See documentation

Alex Kucherenko
  • 20,168
  • 2
  • 26
  • 33
6

It looks like your incoming string is doubly JSON encoded. You should decode it, then decode that again.

Here's my best guess as to how you might do that in Java:

JSONArray resultArray = new JSONArray(new JSONString(jsonFormattedString));

I'm assuming here that JSONString is a type. Your actual solution may vary.

Under normal circumstances, I'd expect a service to give you JSON straight up. It appears that this services is giving you a string (encoded according to the JSON spec) which contains JSON.

It's the difference between the following:

String someJSON = "[0, 1, 2]";
String doublyEncodedJSON = "\"[0, 1, 2]\"";

Notice the extra leading and trailing quotes? That's because the latter is a string of JSON. You'd have to decode it twice to get the actual object.

jimbo
  • 11,004
  • 6
  • 29
  • 46
  • And how exactly do I do that sir ? – Swayam Dec 18 '12 at 19:21
  • Added my best guess---I don't do Java development often, but I work with JSON daily. Good luck! – jimbo Dec 18 '12 at 19:27
  • Well, actually sir.. I just replaced the \" with " and tested the resultant string here http://www.jsoneditoronline.org/ . It showed up properly, the way I expected it to. – Swayam Dec 18 '12 at 19:29
  • Yep, I agree that it works for the particular example data that you're currently getting back from the third-party JSON service. I explain in a comment on the other answer why this masks a hidden bug which will appear when the data eventually contains a real backslash. – jimbo Dec 18 '12 at 19:32
  • Yes sir. I do understand that. I will have a look at how to double decode JSON in java. – Swayam Dec 18 '12 at 19:35
6

You can just use:

str.replace("\\","");

replace takes string as param, replaceAll uses RegEx. it may work like this also:

str.replaceAll("\\\\", "");
d.raev
  • 9,216
  • 8
  • 58
  • 79
1
jsonObj.toString()
        .replace("\"[", "[").replace("]\"", "]")
        .replace("\\\"{", "{").replace("}\\\"", "}")
        .replace("\\\\\\\"", "\"")