[SalesForce] RestContext.request.RequestBody encoding/decoding %5D

I have a REST service which is receiving the encoded body of a post request, and I'm not able to decode the body into a valid json string for parsing. I also don't have much control over the formatting of the request generated by the 3rd party website, so I'm wondering whether the string can be converted with some Apex, or whether it needs to be adjusted on the website before it is sent to Salesforce?

@HttpPost
global static void createAccount() {    
    RestRequest req = RestContext.request;
    System.debug(req.requestBody.toString());

DEBUG STATEMENT:
“request%5Baccount%5D%5BName%5D=Greg%…"

this throws the following error: "[{\"message\":\"Unexpected character ('r' (code 114)): expected a valid value (number, String, array, object, 'true', 'false' or 'null') at [line:1, column:2]\",\"errorCode\":\"JSON_PARSER_ERROR\"}]"

Obviously this isn't being recognized as JSON and thus won't be parsed – is there a way to decode the request body in apex and convert it to valid json – or should this be done by the website where the request is initiated?

Any help appreciated? Thanks

Best Answer

Your text is URL-encoded, so you first need to decode it:

String decodedText = EncodingUtil.urlDecode(req.getBody(), 'utf-8');

It still doesn't look like normal JSON, as the payload starts off as:

request[account][Name]=Greg...

I'm pretty sure this is sourced from PHP, although I could be wrong. Regardless, not being regular JSON, you probably need to decode it as parameters:

PageReference ref = new PageReference('a?'+decodedText);
String accountName = ref.getParameters().get('request[account][Name]');

I expect this will end up being a non-trivial amount of work, though.

If you can have the website developers fix it, make sure they're using actual JSON, not just some URL encoded parameters or some default toString implementation. Most web scripting languages have the ability to convert a native object to JSON strings.