1

I have a rest service which requires a string input and returns a string response. Currently when i test this on workbench, i am getting the following error.

message: Unexpected parameter encountered during deserialization: Courses at [line:3, column:5] errorCode: JSON_PARSER_ERROR

My rest service code is below

@RestResource(urlMapping='/tortal/v2/*')
global with sharing class TortalRestInterfaceMod 
{


    @HttpPut
    global static String processFile(String courseInput)
    { 
        String response;
        Courses result = new Courses();
        result = (Courses) (JSON.deserialize(courseInput,  Courses.class));   
        system.debug('result ' + result);
        for(CoursesData courseObj: result.courses )
        {
            response = 'courseid'+ courseObj.CourseName;
            response += 'courseName'+courseObj.CourseId; 

        } 

        return response;

    }


    public class CoursesData 
    {
        public String CourseId ;  
        public String CourseName;        
    }

    public class Courses
    {
        public Courses()
        {
            Courses = new List<CoursesData>();
        }

        public List<CoursesData> Courses;


    }
}

The rest json string which i use for input to test the rest service on workbench is below.

{
  "courses":  
  [
    {
      "CourseId" : "301",
      "CourseName" : "Basic Hardwood Installation"
    },
    {
      "CourseId" : "401",
      "CourseName" : "Advanced Hardwood Installation"
    }
  ]
}

Could you tell me what is wrong with my code? Do i need to register this webservice as a connected app as well?

3

When you use a parameter, salesforce attempts to deserialize the parameters for you. Here's the example from Apex REST Methods:

@RestResource(urlMapping='/user_defined_type_example/*')
global with sharing class MyOwnTypeRestResource {

    @HttpPost
    global static MyUserDefinedClass echoMyType(MyUserDefinedClass ic) {
        return ic;
    }

    global class MyUserDefinedClass {

        global String string1;
        global String string2 { get; set; }
        private String privateString;
        global transient String transientString;
        global static String staticString;

    }

}

And demonstrate that the request can accept XML or JSON:

JSON

{
    "ic" : {
                "string1" : "value for string1",
                "string2" : "value for string2",
                "privateString" : "value for privateString"
            }
}

XML

<request>
    <ic>
        <string1>value for string1</string1>
        <string2>value for string2</string2>
        <privateString>value for privateString</privateString>
    </ic>
</request>

So, as you can see, your code wouldn't work as written, because you've provided a parameter, and salesforce attempts to parse your payload for you.

You have two choices here: change your parameter list, or use RestContext.request.requestBody.

Changing your parameter list means you'd do something like this:

global static String processFile(List<CourseData> courses) {

Note that in the method with parameters, the outer wrapper class is not needed, as "courses" is mapped to the "courses" parameter.

Or, you could stick with your own JSON parsing:

global static String processFile() { // No parameters here
    Courses data = (Courses)JSON.deserialize(RestContext.request.requestBody.toString(), Courses.class);

The parameter version is a bit more flexible, as it allows the client to pass either XML or JSON with no change to the Apex Code, while the no-parameter version might be more useful if you want to force a specific format or do custom processing on the payload.

  • perfect explanation!! I went with the parameter approach and it worked.. – buyan kumar Oct 15 '16 at 1:04
0

I don't have a great answer... sort of the result of a similar trial and error effort.

I think if you change your JSON body to:

{
  "courseInput":  
  [
    {
      "CourseId" : "301",
      "CourseName" : "Basic Hardwood Installation"
    },
    {
      "CourseId" : "401",
      "CourseName" : "Advanced Hardwood Installation"
    }
  ]
}

... you might get different (maybe better?) results. Try changing the name of the JSON to match you methods input parameter name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.