[SalesForce] Salesforce JSON Error : |FATAL_ERROR|System.JSONException: Illegal value for primitive

I am trying to run this code, I am getting this error in Apex Salesforce Console

*|FATAL_ERROR|System.JSONException: Illegal value for primitive*

public class content {
        public String MTType;
        public String MTTitle;
        public List<String> body;
    }
    // JSON string that contains a content object.
    String JSONContent =
        '{"content":{'+
          '"MTType":"text/html",'+
          '"MTTitle":"Test Builder",'+
          '"body":['+
             '" <div id=\"section_1\" class=\"mt-page-section\"><span id=\"Overview\"></span><h2 class=\"editable\">Overview</h2></div>",'+
             '{'+
              '  "@target":"toc",'+
              '  "#text":"<ol style=\"list-style-type:none; margin-left:0px; padding-left:0px;\"><li><span>1.</span> <a href=\"#Overview\" rel=\"internal\">Overview</a></li><li><span>2.</span> <a href=\"#Building_an_Objective-Based_Test\" rel=\"internal\">Building an Objective-Based Test</a><ol style=\"list-style-type:none; margin-left:0px; padding-left:15px;\"><li><span>2.1.</span> <a href=\"#What_are_Learning_Paths.3F\" rel=\"internal\">What are Learning Paths?</a></li></ol></li></ol>"'+
             '}'+
          ']'+
       '}'+
    '}';

JSONParser parser = 
   JSON.createParser(JSONContent);
// Make calls to nextToken() 
// to point to the second
// start object marker.
parser.nextToken();
parser.nextToken();
parser.nextToken();
// Retrieve the Person object
// from the JSON string.
content obj = 
   (content)parser.readValueAs(
      content.class);
System.Debug(obj.body[0]);
parser.skipChildren();  

I have tested the validity of JSON String here at

http://jsonformatter.curiousconcept.com/

Here I am pasting JSON String Again

{
   "content":{
      "MTType":"text/html",
      "MTTitle":"Test Builder",
      "body":[
         " <div id=\"section_1\" class=\"mt-page-section\"><span id=\"Overview\"></span><h2 class=\"editable\">Overview</h2>  <p>You can use Test Builder to create custom objective&#8208;based tests using objectives from the Odyssey curriculum, your standard state objectives, or your own custom district or school objectives. As part of the test&#8208;building process, you first select a standard set, subject, and level; then, you select the desired associated objectives to include in the custom test.&nbsp;</p> <p>&nbsp;</p> <p>You can make changes to the order and number of objectives for each test and to the test item property settings. All of the tests you create can be saved and edited.</p> </div><div id=\"section_2\" class=\"mt-page-section\"><span id=\"Building_an_Objective-Based_Test\"></span><h2 class=\"editable\">Building an Objective-Based Test</h2>  <p><span style=\"font-size: 12px; line-height: 1.5;\">On the Test Builder page, first select a set of standards from the menu provided. </span>From the Objective Additions drop&#8208;down list on the Select Standard screen of the test builder section, specify how you want objectives to be added to a custom test:</p> <p>&nbsp;</p> <ul> <li><strong>Add to existing objectives</strong> adds newly selected objectives to existing objectives in the test, if any. Select this option when you build a custom test that includes objectives from multiple subjects and/or levels. For example, if you want to include objectives from more than one subject area&mdash;Math and Geometry&mdash;you will select Add to existing objectives.</li> <li><strong>Replace all objectives</strong> includes only the newly selected objectives in the test, replacing any existing objectives, if any, that were previously defined. This option allows you to start building a custom test from the beginning and also may be used when you are editing an existing custom test.</li> </ul> <p>&nbsp;</p> <p>It is important to know that the Objective-Based test is independent from an assignment. For instance, if you copy an assignment containing an Objective-based test, you will have control over the assignment properties, but not the test properties (unless you also created the test). Attempting to edit a test that you did not create may produce the following error message:</p> <p><strong><span style=\"background-color:#faebd7;\">CAUTION:</span></strong><span style=\"background-color:#faebd7;\">&nbsp;If you copy an assignment that includes an objective&#8208;based test, and then edit the test, your edits are applied to the original objective&#8208;based test. See Editing Custom Objective&#8208;based Tests.</span></p> <div id=\"section_3\" class=\"mt-page-section\"><span id=\"What_are_Learning_Paths.3F\"></span><h3 class=\"editable\">What are Learning Paths?</h3>  <p>Some assignments include a&nbsp;<strong>learning path</strong>, a set of activities designed to cover the objectives a student has not mastered in an objective&#8208;based test, an exit exam (for high&#8208;school level curriculum), or a test external to Odyssey. You can build an objective&#8208;based using the Odyssey curriculum; create one with custom assessment objectives; or create one using your state&rsquo;s objectives (where applicable). Odyssey will create a learning path based on objective&#8208;based tests. Learning paths based on customized objectives must be created manually.&nbsp;<br /> <br /> Also, a teacher may administer an exit exam as part of an Odyssey high school course. Alternatively, in schools that have purchased support for Odyssey&rsquo;s Test Translator, the test is administered outside of Odyssey Manager. Administrators use Test Translator to import test results into Odyssey Manager and a learning path is automatically created based on the results of the NWEA or state test.&nbsp;</p></div></div>",
         {
            "@target":"toc",
            "#text":"<ol style=\"list-style-type:none; margin-left:0px; padding-left:0px;\"><li><span>1.</span> <a href=\"#Overview\" rel=\"internal\">Overview</a></li><li><span>2.</span> <a href=\"#Building_an_Objective-Based_Test\" rel=\"internal\">Building an Objective-Based Test</a><ol style=\"list-style-type:none; margin-left:0px; padding-left:15px;\"><li><span>2.1.</span> <a href=\"#What_are_Learning_Paths.3F\" rel=\"internal\">What are Learning Paths?</a></li></ol></li></ol>"
         }
      ]
   }
}

Can anybody please advice, what am I doing wrong here ?

Here is the content class

public class content {
        public String MTType;
        public String MTTitle;
        public List<String> body;
    }

In here, I want to ignore the child of body, we only want to show the body on the Visualforce page, by ignoring the child, i therefore had used Salesforce method called

parser.skipChildren();  

Best Answer

The problem seems to be your body is String array

public List<String> body;

But you second object in json is an object.

{
        "@target":"toc",
...

Add a 4th object to your content class and it should be ok.

public class content {
    public String MTType;
    public String MTTitle;
    public List<String> body;
    public TargetText targetText;
}

public class TargetText{
    String target;
    String text;
}

And the json would be something like this

"content":{
...
body : ["...."],
   targetText:{
   target:"..."
   text:"..."
   }
}