[SalesForce] JSON parsing an array – not reading object

Consider the following class, modified from this gist https://gist.github.com/sravalaparthi/69d76a710fb3689b0859
when it creates the objectWrapper object (qw), it's not populating it with the parsed JSON object. Can anyone see what I'm doing wrong here?

    public class JSONParserDemo {

    String jsonstring ='{"item":[{"field1":"0040030579","field2":"2014-01-30",'
                + '"field3":"100","field4":"2014-01-30"}]}';
    List<objectWrapper> parsedObjects = new List<objectWrapper>();

    public List<objectWrapper> getparsedObjects(){
        // Create a JSON Parser from String.
        JSONParser parser = JSON.createParser(jsonstring);
        string s = jsonstring;
        while (parser.nextToken() != null) {
            if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
                (parser.getText() == 'item')){
                system.debug('found "item"');   // finds this ok ("item")
                 s = (String)parser.readValueAs(String.class);
                system.debug('s = ' + JSON.serialize(s));
                while (parser.nextToken() != null) {
                    // Check for JSON array starting.
                    // START_ARRAY This token is returned when '[' is encountered.
                    if (parser.getCurrentToken() == JSONToken.START_ARRAY) {
                        system.debug('found START_ARRAY');      // finds this ok ("[")
                         s = (String)parser.readValueAs(String.class);
                        system.debug('s = ' + JSON.serialize(s));
                        // Check for JSON object starting
                        //  START_OBJECT This token is returned when '{' is encountered.
                        while (parser.nextToken() != null) {
                            if (parser.getCurrentToken() == JSONToken.START_OBJECT) {
                                system.debug('found START_OBJECT: ' + parser.getText());    // finds this ok ("{")
                                // Read entire object, including its array of line items.
                                objectWrapper qw = ( objectWrapper)parser.readValueAs(objectWrapper.class);
                                system.debug('qw = ' + JSON.serialize(qw));     // returns a null object :(
                                parsedObjects.add(qw);
                                parser.skipChildren();
                            }
                        }
                    }
                }
            }
        }
         return parsedObjects;  
    }

    //Inner class of required JSON object type
    public class objectWrapper
  {
        public string f1 {get;set;}
        public string f2 {get;set;}
        public string f3 {get;set;}
        public string f4 {get;set;}
  }

}

Thanks.

Best Answer

The values in your JSON are field1, field2, field3, and field4, but in your wrapper class, defined only as f1, f2, f3, and f4. The names need to match in order to use readValueAs. Your code is about as complicated as it could be. Here's how I'd parse your incredibly complex example:

public class Item {
    public String field1;
    public String field2;
    public String field3;
    public String field4;
}

public class Wrapper {
    public List<Item> item;
}

public static Wrapper parse(String json) {
    return (Wrapper) System.JSON.deserialize(json, Wrapper.class);
}

You should generally leave parsing of this complexity to objects that would be difficult/impossible to model in generic code, perhaps because of field names or depth complexity.