0

So I am using the amiibo api to pull data, and display what is returned in a table. For now, I'm just putting the series in the table to make sure it works, but it doesn't!

Here is my table:

<table class="table table-striped table-hover table-sm">
            <thead>
                <tr>
                    <th class="col-sm-1" scope="col">#</th>
                    <th class="col-sm-11" scope="col">Amiibo</th>
                </tr>
            </thead>
            <c:forEach var="amiibo" items="${amiibos}" varStatus="status">
                <tr>
                    <th scope="row">${status.count}</th>
                    <td>${amiibo.amiiboSeries}</td>
                </tr>
            </c:forEach> 
        </table>

And here is my servlet that pulls that the api data and puts it into a list:

String json = callAmiiboApi(input.getAmiibo());

        // Check for valid json format.  If false, String contains an error message.
        if (json.startsWith("{") || json.startsWith("[")) {
            Gson gson = new Gson();
            ArrayList<Amiibo> amiibos = gson.fromJson(json, new TypeToken<ArrayList<Amiibo>>(){}.getType());

            //get list of elements 
            if (!amiibos.isEmpty() && amiibos.size() > 0) {
                request.setAttribute("amiibos", amiibos);
            }  
        }

Here is my object:

public class Amiibo implements Serializable
{
    public String amiiboSeries;
    public String character;
    public String gameSeries;
    public String head;
    public String image;
    public String name;
    public String[] release;
    public String tail;
    public String type;

    public Amiibo()
    {
        amiiboSeries = "";
        character = "";
        gameSeries = "";
        head = "";
        image = "";
        name = "";
        release = new String[0];
        tail = "";
        type = "";
    }

    public String getAmiiboSeries()
    {
        return amiiboSeries;
    }

This is the error I get:

java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

Does anyone know what I am doing wrong in pulling this data? I think the api is accessed fine, I believe my issue is in how I am displaying it (potentially when I put it into a list?).

-- edit --

This is my input class to get the user input

import java.io.Serializable;

public class Input implements Serializable {
    private String amiibo;

    public Input() {
        this("");
    }

    public Input(String amiibo) {
        this.amiibo = amiibo;
    }

    public String getAmiibo() {
        return amiibo;
    }

    public void setAmiibo(String amiibo) {
        this.amiibo = amiibo;
    }  
}
burgoyne
  • 143
  • 2
  • 15

1 Answers1

1

Crete wrapper object:

class AmiiboResponse {

    private List<Amiibo> amiibo;

    public List<Amiibo> getAmiibo() {
        return amiibo;
    }

    public void setAmiibo(List<Amiibo> amiibo) {
        this.amiibo = amiibo;
    }
}

and deserialise in this way:

List<Amiibo> amiibos = gson.fromJson(json, AmiiboResponse.class).getAmiibo();
Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
  • Thank you! So I think I already have something similar to your suggestion. I have edited my question to add the class in question. – burgoyne Mar 14 '19 at 01:08
  • @burgoyne, Your class if for input which you send to `REST API`. `AmiiboResponse` class should be used to deserialise output from `REST API`. – Michał Ziober Mar 14 '19 at 01:13
  • I gwt this error when attempting your solution: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 241 path $.amiibo[0].release – burgoyne Mar 14 '19 at 01:17
  • @burgoyne, and this is because in your model you have `public String[] release;` but it should be `public Map release;` This is an object in documentation, so you should use `Map` here. – Michał Ziober Mar 14 '19 at 01:18
  • Thank you for your help, but unfortunately I still get the same error after removing the [] and fixing the methods that use it. Just saw your edit - how would I alter the other methods that use release after adding the Map to it? I've never seen that used before. – burgoyne Mar 14 '19 at 01:21
  • @burgoyne, `Map` map is a quite normal approach when you have random key names in `JSON`. This is how it looks like in this case. I am not sure what do you mean by "altering other methods". You can iterate `Map` as simple as `array` in Java. See [How do I efficiently iterate over each entry in a Java Map?](https://stackoverflow.com/questions/46898/how-do-i-efficiently-iterate-over-each-entry-in-a-java-map). For all these methods where you used `String[] release` param, use `Map release` param and it should work for you. – Michał Ziober Mar 14 '19 at 01:27
  • Thanks for that link. I mean what should I change this line to: release = new String[0]; ? – burgoyne Mar 14 '19 at 01:32
  • @burgoyne, you do not need to instantiate new `Map` object but if you really need you can write: `new HashMap<>();`. – Michał Ziober Mar 14 '19 at 01:33
  • 1
    That did it. Thank you so much for your help! – burgoyne Mar 14 '19 at 01:37