JSON(I am working with): JSONLinter confirms this is a valid JSON.
{
"errors": [
{
"params": {
"password": "size must be between 4 and 30",
"loginId": "must match \"^[a-zA-Z0-9_]*$\""
}
}
]
}
Attempt 1(Using JSONParser:
String str = '{ "errors": [ { "params": { "password": "size must be between 4 and 30", "loginId": "must match \"^[a-zA-Z0-9_]*$\"" } } ] }';
JSONParser parser = JSON.createParser(str);
while(parser.nextToken() != null){
parser.nextToken();
}
Fails:
▸ ERROR: System.JSONException: Unexpected character ('^' (code
94)): was ▸ expecting comma to separate OBJECT entries at input
location [1,99] ▸ ERROR: Class.System.JSONParser.nextToken: line
94, column 1 ▸ AnonymousBlock: line 3, column 1 ▸
AnonymousBlock: line 3, column 1
Attempt 2(JSON2Apex option):
public class JSON2Apex {
public class Errors {
public Params params;
}
public List<Errors> errors;
public class Params {
public String password;
public String loginId;
}
}
String str = '{ "errors": [ { "params": { "password": "size must be between 4 and 30", "loginId": "must match \"^[a-zA-Z0-9_]*$\"" } } ] }';
JSON2Apex obj = (JSON2Apex)JSON.deserialize(str, JSON2Apex.class);
Fails:
▸ ERROR: System.JSONException: Unexpected character ('^' (code
94)): was ▸ expecting comma to separate OBJECT entries at [line:1,
column:99] ▸ ERROR: Class.System.JSON.deserialize: line 15, column
1 ▸ AnonymousBlock: line 2, column 1 ▸ AnonymousBlock: line 2,
column 1
Attempt 3(deserializeUntyped):
String str = '{ "errors": [ { "params": { "password": "size must be between 4 and 30", "loginId": "must match \"^[a-zA-Z0-9_]*$\"" } } ] }';
Map<String,Object> jsonObj = (Map<String,Object>)JSON.deserializeUntyped(str);
Fails:
▸ ERROR: System.JSONException: Unexpected character ('^' (code
94)): was ▸ expecting comma to separate OBJECT entries at [line:1,
column:99] ▸ ERROR: Class.System.JSON.deserializeUntyped: line 11,
column 1 ▸ AnonymousBlock: line 2, column 1 ▸ AnonymousBlock:
line 2, column 1
Attempt 4(replace the problem causing double quote in JSON):
String str = '{ "errors": [ { "params": { "password": "size must be between 4 and 30", "loginId": "must match \"^[a-zA-Z0-9_]*$\"" } } ] }';
Map<String,Object> jsonObj = (Map<String,Object>)JSON.deserializeUntyped(str.replaceAll('\"', '\\"'));
Still fails:
▸ ERROR: System.JSONException: Unexpected character ('^' (code
94)): was ▸ expecting comma to separate OBJECT entries at [line:1,
column:99] ▸ ERROR: Class.System.JSON.deserializeUntyped: line 11,
column 1 ▸ AnonymousBlock: line 2, column 1 ▸ AnonymousBlock:
line 2, column 1
I have looked into the below similar questions but still don't see any solution:
Best Answer
I'll try to illustrate this.
This is valid JSON.
This is not:
Why? Because in Apex, backslash is an escape character in a string literal. If you want that backslash to carry through to the in-memory representation of the string (your JSON), you must escape it in your source code:
Otherwise, Apex removes it, yielding an in-memory string that is not valid JSON because nested quote marks are not escaped:
You don't need to use
replaceAll()
or anything fancy to fix this (and in fact, you can't - by the time you could callreplaceAll()
, the string's already broken and has no backslashes in it).The problem is not in your logic. It's just in how you're writing string literals in your source code.