How to fix Out of START_ARRAY token Error

20,581

Your json string is correct, but not for the object you expect, as someone mentioned already, you need to use a List

import java.io.IOException;
import java.util.List;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;


public class ParseJson {

    private static final String jsonString = "[{\"name\":\"foo\",\"slug\":\"foo2\",\"locales\":[\"foo3\"],\"hostname\":\"foo4\",\"region_tag\":\"foo5\"},{\"name\":\"foo\",\"slug\":\"foo2\",\"locales\":[\"foo3\"],\"hostname\":\"foo4\",\"region_tag\":\"foo5\"},{\"name\":\"foo\",\"slug\":\"foo2\",\"locales\":[\"foo3\"],\"hostname\":\"foo4\",\"region_tag\":\"foo5\"},{\"name\":\"foo\",\"slug\":\"foo2\",\"locales\":[\"foo3\"],\"hostname\":\"foo4\",\"region_tag\":\"foo5\"}]";

    public static void parse()  {

        try {

            TypeReference<List<Shards>> typeRef = new TypeReference<List<Shards>>() { };
            ObjectMapper mapper = new ObjectMapper();
            List<Shards> list = mapper.readValue(jsonString, typeRef);

            for ( Shards s : list )
            {
                s.printDebug();
            }

            ShardsResponse sr = new ShardsResponse(list);
            String srString = mapper.writeValueAsString(sr);

            System.out.println("srString: " + srString );

            TypeReference<ShardsResponse> typeRef2 = new TypeReference<ShardsResponse>() { };
            ShardsResponse sr2 = mapper.readValue(srString, typeRef2);

            sr2.printDebug();


        } catch ( IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
       ParseJson.parse();
    }

}

Edit: If you expect a ShardsResponse back, your json string should look like this:

{"shards":[{"locales":["foo3"],"name":"foo","hostname":"foo4","slug":"foo2","region_tag":"foo5"},{"locales":["foo3"],"name":"foo","hostname":"foo4","slug":"foo2","region_tag":"foo5"},{"locales":["foo3"],"name":"foo","hostname":"foo4","slug":"foo2","region_tag":"foo5"},{"locales":["foo3"],"name":"foo","hostname":"foo4","slug":"foo2","region_tag":"foo5"}]}

Easiest way to figure out what the json will look like is to dump it out:

ShardsResponse sr = new ShardsResponse(list);
String srString = mapper.writeValueAsString(sr);
System.out.println("srString: " + srString );

Edit:

Adding additional Classes for clarity:

ShardsResponses.java

import java.util.ArrayList;
import java.util.List;


public class ShardsResponse {

    private List<Shards> shards = new ArrayList<Shards>();

    public ShardsResponse() { }

    public ShardsResponse( List<Shards> shards)
    {
        this.shards = shards;
    }

    public List<Shards> getShards() {
        return shards;
    }

    public void setShards(List<Shards> shards) {
        this.shards = shards;
    }

    public void  printDebug()
    {
        for ( Shards s : shards)
        {
             s.printDebug();
             System.out.println("");
        }
    }


}

Shards.java:

import java.util.List;


public class Shards {

    private List<String> locales;
    private String name;
    private String hostname;
    private String slug;
    private String region_tag;


    public List<String> getLocales() {
        return locales;
    }
    public void setLocales(List<String> locales) {
        this.locales = locales;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getHostname() {
        return hostname;
    }
    public void setHostname(String hostname) {
        this.hostname = hostname;
    }
    public String getSlug() {
        return slug;
    }
    public void setSlug(String slug) {
        this.slug = slug;
    }
    public void printDebug()
    {
        System.out.println("name: " + name);
        System.out.println("hostname: " + hostname);
        System.out.println("slug: " + slug);
        System.out.println("region_tag: " + region_tag);
        for ( String s : locales )
        {
            System.out.println("Locals: " + locales);
        }
    }
    public String getRegion_tag() {
        return region_tag;
    }
    public void setRegion_tag(String region_tag) {
        this.region_tag = region_tag;
    }
}
Share:
20,581
dummyDroid
Author by

dummyDroid

Updated on November 24, 2020

Comments

  • dummyDroid
    dummyDroid over 3 years

    Can anybody say where I am doing wrong. I have json like that

    [{"name":"foo","slug":"foo2","locales":["foo3"],"hostname":"foo4","region_tag":"foo5"},{"name":"foo","slug":"foo2","locales":["foo3"],"hostname":"foo4","region_tag":"foo5"},{"name":"foo","slug":"foo2","locales":["foo3"],"hostname":"foo4","region_tag":"foo5"},{"name":"foo","slug":"foo2","locales":["foo3"],"hostname":"foo4","region_tag":"foo5"}]
    

    And I parse to this class.

    @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
    @JsonPropertyOrder({
    "shards"
    })
    
    public class ShardsResponse extends Response{
    
    @JsonProperty("shards")
    private List<Shards> shards = new ArrayList<Shards>();
    
    /**
     * 
     * @return
     *     The shards
     */
    @JsonProperty("shards")
    public List<Shards> getShards() {
        return shards;
    }
    
    /**
     * 
     * @param shards
     *     The shards
     */
    @JsonProperty("shards")
    public void setShards(List<Shards> shards) {
        this.shards = shards;
    }
    }
    

    And Shards class is :

    /**
    
    
    * 
     * @return
     *     The locales
     */
    @JsonProperty("locales")
    public List<String> getLocales() {
        return locales;
    }
    
    /**
     * 
     * @param locales
     *     The locales
     */
    @JsonProperty("locales")
    public void setLocales(List<String> locales) {
        this.locales = locales;
    }
    
    /**
     * 
     * @return
     *     The name
     */
    @JsonProperty("name")
    public String getName() {
        return name;
    }
    
    /**
     * 
     * @param name
     *     The name
     */
    @JsonProperty("name")
    public void setName(String name) {
        this.name = name;
    }
    
    /**
     * 
     * @return
     *     The hostname
     */
    @JsonProperty("hostname")
    public String getHostname() {
        return hostname;
    }
    
    /**
     * 
     * @param hostname
     *     The hostname
     */
    @JsonProperty("hostname")
    public void setHostname(String hostname) {
        this.hostname = hostname;
    }
    
    /**
     * 
     * @return
     *     The slug
     */
    @JsonProperty("slug")
    public String getSlug() {
        return slug;
    }
    
    /**
     * 
     * @param slug
     *     The slug
     */
    @JsonProperty("slug")
    public void setSlug(String slug) {
        this.slug = slug;
    }
    }
    

    So I'm using ObjectMapper.readValue(jsontext, responseclass)

    JSONObject object = new JSONObject(JsonString);
    
    JsonString = "";
    Iterator<String> keys= object.keys();
    
    while (keys.hasNext()){
    
        String keyValue = (String)keys.next();
        JsonString= JsonString+ object.getString(keyValue);
    }
    
    JsonString= JsonString.substring(1, JsonString.length()-1);
    
    Object response = ObjectMapper.readValue(JsonString, ShardsResponse.class);
    

    At the last I am getting out of START_ARRAY token. Please anybody tell me what's wrong.

    Cause I'm trying so much things, but I never find the solution.

    How can I fix it.