2

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

4 Answers 4

4

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": []
    }
 ]
}
2
  • 1
    Dev, why i cannot Pass without "jsonBodyList" directly? give some Gyaan on this.
    – Arvind
    Commented Jun 22, 2018 at 11:30
  • Even though the JSON you are sending is an array, the object is used by the platform to describe which method parameter the array will be mapped to, in this case the 'jsonBodyList'
    – sskular
    Commented May 15, 2019 at 14:37
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

2
  • I get the same error again.. Yes there were many unnecessary code i forgot to remove it. last 3 lines were important, Updated the question with the latest error, Basically i want to do a qurey which they are sending and append it to result and send it back They will be sending me around 200 JSON(which includes Query also)
    – Arvind
    Commented Jun 20, 2018 at 10:34
  • @kishore Try the suggested solution from @devendra as: req.setBody('{"jsonBodyList":' + JSON.serialize(jsonBodyList) + '}' and with the above code that I have provided. Let me know if it goes ok. Commented Jun 20, 2018 at 14:16
2

I just had similar issue and I think it is important to know there are 2 options:

  1. 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"
        }
    ]
}
  1. 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.

0

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .