I have a Post method where the other system will be sending me the JSON like this
[{ "query": "SELECT AccountId,Birthdate,FirstName FROM Contact WHERE(((FirstName = 'Vikram3' AND AssistantName = 'test3' )))", "commonIndex": 0, "resultSize": 0, "result": [] }, { "query": "SELECT AccountId,Birthdate,FirstName FROM Contact WHERE (((FirstName = 'Vikram4' AND AssistantName = 'test4' )))", "commonIndex": 1, "resultSize": 0, "result": [] }, { "query": "SELECT AccountId,Birthdate,FirstName FROM Contact WHERE (((FirstName = 'Vikram5' AND AssistantName = 'test5')))", "commonIndex": 2, "resultSize": 0, "result": [] } ]
And below is my class which is converted to wrapper obj.
@RestResource(urlMapping='/Portqii/*') global with sharing class Portqii { global class fromJSON { public String query; public Integer commonIndex; public Integer resultSize; public string result; } @HttpPost global static string returnRequest(fromJSON jsonBody ) { RestRequest request = RestContext.request; RestResponse response = RestContext.response; response.addHeader('Content-Type','applicatin/json'); fromJSON jsonBody1=jsonBody ; jsonBody1 = (fromJSON) JSON.deserialize(request.requestBody.toString(),fromJSON.class); return string.valueof(jsonBody1) ; } }
And i get this error, while executing it in workbench
JSON_PARSER_ERROR
message: JSON request body must be an object at [line:1, column:2]
errorCode: JSON_PARSER_ERROR
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
So yeah it worked.
you can try this. the issue was your json request is not right.
you were trying to access list of your wrapper class. do this and it will work.
{“jsonBodyList” : your previus json here}
{"jsonBodyList": [{ "query": "SELECT AccountId,Birthdate,FirstName FROM Contact WHERE(((FirstName = 'Vikram3' AND AssistantName = 'test3' )))", "commonIndex": 0, "resultSize": 0, "result": [] }, { "query": "SELECT AccountId,Birthdate,FirstName FROM Contact WHERE (((FirstName = 'Vikram4' AND AssistantName = 'test4' )))", "commonIndex": 1, "resultSize": 0, "result": [] }, { "query": "SELECT AccountId,Birthdate,FirstName FROM Contact WHERE (((FirstName = 'Vikram5' AND AssistantName = 'test5')))", "commonIndex": 2, "resultSize": 0, "result": [] } ] }
Method 2
In fact the response that you get is a list of fromJSON object.
Below is the correct form (check also the other corrections I’ve made):
@RestResource(urlMapping='/Portqii/*') global with sharing class Portqii { global class fromJSON { global String query; global Integer commonIndex; global Integer resultSize; global List<string> result; //it's a list of string actually } @HttpPost global static string returnRequest(List<fromJSON> jsonBodyList ) { // I'm not sure why lines below are included.. seems unnecessary.. // I've commented out them //RestRequest request = RestContext.request; //RestResponse response = RestContext.response; //response.addHeader('Content-Type','applicatin/json'); // You are parsing it as fromJSON object // and then converting it back to a string on the return statement.. why?! //fromJSON jsonBody1 = (fromJSON) JSON.deserialize(request.requestBody.toString(),fromJSON.class); //return string.valueof(jsonBody1); // instead, you can try to manipulate the jsonBodyList for(fromJSON fjs : jsonBodyList){ ... fjs.resultSize = 2; //for e.g. ... } // and then return it in the end return JSON.serialize(jsonBodyList); } }
Let me know if it helps
Method 3
Your sample data is an array of object so you should be using List instead of fromJSON while desrializing. Also result variable should be list as well in fromJSON class
Method 4
I just had similar issue and I think it is important to know there are 2 options:
- solution proposed in previous answers to have request body in form of an object instead of array of objects. This way we can specify Apex method’s input parameters and type them already.
@HttpPost global static String doPost(List<Apple> apples) { doSomething(apples); return 'success'; }
{ "apples": [ { "color": "red", "id": "1" }, { "color": "green", "id": "2" } ] }
- Or you can still have array of objects as top level in your request JSON but you will need to
deserialize(Strict)
the request body on your own:
@HttpPost global static String doPost() { String requestBody = RestContext.request.requestBody.toString(); List<Apple> apples = (List<Apple>) JSON.deserializeStrict(requestBody, List<Apple>.class); doSomething(apples); return 'success'; }
[ { "color": "red", "id": "1" }, { "color": "green", "id": "2" } ]
Option 1 seems to be more readable as you upfront see what should you receive in request. Also some systems are able to automatically fetch expected request structure using Metadata API. You don’t need to deserialize on your own.
Option 2 seems to be more standard in terms of expected request format.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0