0

could you please point out my error? I have a very simple class and a webservice:

public class JSONFactory {
public Integer id;
public String name;
public String lastName;
public JSONFactory(Integer a, String b, String c){
    this.id = a;
    this.name = b;
    this.lastName = c;
    }
}



@RestResource(urlMapping='/Johnny')
global class WebServiceFactory {
    @HttpGet
    global static String getRecord() {
        List<JSONFactory> JSONs = new List<JSONFactory>();
        for(integer i = 0; i<4; i++){
            JSONs.add(new JSONFactory(i, 'Jan' + i, 'Test' + i));
        
            }
        return JSONs.toString();
    }
}

The web service should return a JSON made of a list of objects. According to the documentation, this happens automatically:

The response is either the serialized form of the method return value or it's the value of the responseBody property based on the following rules:

  • If the method returns void, then Apex REST returns the response in the responseBody property. If the method returns a value, then Apex
  • REST serializes the return value as the response.

After calling the getRecord method, the system debugs:

14:45:08:352 USER_DEBUG [43]|DEBUG|"(JSONFactory:[id=0, lastName=Test0, name=Jan0], JSONFactory:[id=1, lastName=Test1, name=Jan1], JSONFactory:[id=2, lastName=Test2, name=Jan2], JSONFactory:[id=3, lastName=Test3, name=Jan3])"

This is not a valid JSON and I am having trouble deserializing it into a list of Objects:

List<Object> objs = (List<Object>)JSON.deserializeUntyped(res.getBody());

I'm getting an exception:

FATAL_ERROR System.TypeException: Invalid conversion from runtime type String to List<ANY>

3 Answers 3

1

To allow automatic serialization, use the return type of any serializable type:

@HttpGet
global static List<JSONFactory> getRecord() {
    List<JSONFactory> JSONs = new List<JSONFactory>();
    for(integer i = 0; i<4; i++){
        JSONs.add(new JSONFactory(i, 'Jan' + i, 'Test' + i));
    
        }
    return JSONs;
}

Salesforce will automatically serialize the results for you, in XML or JSON, depending on the Accept header.

You can read more in the docs.

0

This error occurs because the toString method does not return valid json. To convert the list object to valid json you can use the Apex JSON class provided by Salesforce - https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_Json.htm

@RestResource(urlMapping='/Johnny')
global class WebServiceFactory {
    @HttpGet
    global static String getRecord() {
        List<JSONFactory> JSONs = new List<JSONFactory>();
        for(integer i = 0; i<4; i++){
            JSONs.add(new JSONFactory(i, 'Jan' + i, 'Test' + i));
        
            }
        return System.JSON.serialize(JSONs); 
    }
}
1
  • Hello Tyler, thanks for the response. I tried this yesterday and the payload got serialized twice: salesforce.stackexchange.com/questions/370832/… Is there any other way I could auto serialize a list of objects without returning a list of objects, because that's not possible in a GET REST method.
    – DevelBase2
    Commented Mar 5, 2022 at 15:07
0

The return type .toString() does not generate a JSON formatted String.

You will have to change that to :

@RestResource(urlMapping='/Johnny')
global class WebServiceFactory {
    @HttpGet
    global static String getRecord() {
        List<JSONFactory> JSONs = new List<JSONFactory>();
        for(integer i = 0; i<4; i++){
            JSONs.add(new JSONFactory(i, 'Jan' + i, 'Test' + i));

        }
        return JSON.serialize(JSONs);
    }
}

Only then you will receive a JSON formatted String.

20:24:05.199 (202088269)|USER_DEBUG|[17]|DEBUG|[{"name":"Jan0","lastName":"Test0","id":0},{"name":"Jan1","lastName":"Test1","id":1},{"name":"Jan2","lastName":"Test2","id":2},{"name":"Jan3","lastName":"Test3","id":3}]

After this your List<Object> objs = (List<Object>)JSON.deserializeUntyped(res.getBody()); would work as expected.

5
  • Hello, thanks for the response. I tried this yesterday and got into a problem with the result being serialized twice: salesforce.stackexchange.com/questions/370832/…
    – DevelBase2
    Commented Mar 5, 2022 at 14:37
  • I have pasted the response too, so even if you don't serialize explicitly. The response from server is always serialized and sent to client side. So you don't need to serialize it frankly speaking. I was pointing out the error you are facing above. Adding a toString() wont give a JSON formatted response. Hence you are seeing FATAL_ERROR System.TypeException: Invalid conversion from runtime type String to List<ANY> Commented Mar 5, 2022 at 14:58
  • Ah, I see. Well I tried simply returning a list of objects, but it won't let me as a Rest GET methods can not return lists of objects.
    – DevelBase2
    Commented Mar 5, 2022 at 15:01
  • Not as a return type but you can add it like this RestContext.response.responseBody = Blob.valueOf(JSON.serialize(JSONs)); Commented Mar 5, 2022 at 15:15
  • Thanks a lot man!
    – DevelBase2
    Commented Mar 5, 2022 at 15:38

You must log in to answer this question.

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