user1877061
user1877061

Reputation:

Crash when parsing JSON url using Gson with Volley

I'm fairly new to JSON parsing and very new to Gson library..!

So I wanna view a list of news in a RecyclerView using a JSON url and Volley library to get the data from the url, and I successfully managed to do it, but using regular JSON parsing not Gson.

I wanna do the same thing using Gson, but it just not working..!

I tried to do it, but a crash occurred and after some digging I managed to fix it, but now this crash occurs,..! I think I kinda understand what it means but I can't figure it out the solution..!

CRASH

 java.lang.ClassCastException: java.util.ArrayList cannot be cast 
   to com.alaasamizarifa.pfi.Fragments.News.NewsModel

JSON

    [
     {
    "id": "1",
        "title": "title test1",
    "thumb":          "http://clients.intertech.ps:8080/pfi/userfiles/image/agenda.jpg",
        "body": "Under Construction",
        "lang": "1"
   },
  {
    "id": "2",
        "title": "title test2",
        "body": "Under Construction",

        "lang": "1"
},
{
    "id": "3",
        "title": "title test3",
        "thumb": "http://clients.intertech.ps:8080/pfi/userfiles/image/slide3.png",
        "body": "Under Construction",
        "lang": "1"
},
{
    "id": "4",
        "title": "title test4",
    "thumb": "",
        "body": "Under Construction",
        "lang": "1"
},
{
    "id": "5",
        "title": "title test5",
        "thumb": "http://clients.intertech.ps:8080/pfi/userfiles/image/img1.png",
        "body": "Under Construction",
        "lang": "1"
},
{
    "id": "6",
        "title": "title test6",
        "thumb": "http://clients.intertech.ps:8080/pfi/userfiles/image/news-img1.png",
        "body": "Under Construction",
        "lang": "2"
},
{
    "id": "7",
        "title": "title test7",
        "thumb": "http://clients.intertech.ps:8080/pfi/userfiles/image/news-img1.png",
        "body": "Under Construction",
        "lang": "2"
},
{
    "id": "8",
        "title": "title test8",
        "thumb": "http://clients.intertech.ps:8080/pfi/userfiles/image/news-img1.png",
        "body": "Under Construction",
        "lang": "2"
},
{
    "id": "9",
        "title": "title test9",
        "thumb": "http://clients.intertech.ps:8080/pfi/userfiles/image/news-img1.png",
        "body": "Under Construction",
        "lang": "2"
}


  }
 ]

Here's my original code using regular JSON parsing..! (Worked like a charm)

     mRequestQueue = Volley.newRequestQueue(getActivity());


    final ProgressDialog progressDialog = new ProgressDialog(getActivity());
    progressDialog.setMessage("Loading..");
    progressDialog.show();

    final JsonArrayRequest ArrayRequest = new JsonArrayRequest(JsonURL,

            new Response.Listener<JSONArray>() {


                @Override
                public void onResponse(JSONArray response) {

                    NewsModel model;
                    List<NewsModel> modelData;
                    modelData = new ArrayList<>();

                    for (int i = 0; i<response.length;i++){

                    JSONObject obj = (JSONObject) response.get(i);
                    NewsModelnews = new NewsModel(
                     obj.getString("id"),
                            obj.getString("thumb"),
                            obj.getString("title"),
                            obj.getString("body"),
                            obj.getString("lang"));

                            model.setImageURL(obj.getString("thumb"));
                            model.setID(obj.getString("id"));
                            model.setBody(obj.getString("body"));
                            model.setLang(obj.getString("lang"));
                            model.setTitle(obj.getString("title"));

                    modelData.add(model);

                     } //end of for loop


                    adapter = new NewsAdapter(modelData, getActivity());
                    recyclerView.setAdapter(adapter);

                    progressDialog.dismiss();
                }
            },

            new Response.ErrorListener() {
                @Override
                 public void onErrorResponse(VolleyError error) {
                    Toast.makeText(getActivity(), "Data Response Error", Toast.LENGTH_SHORT).show();
                }
            }
    );

    mRequestQueue.add(ArrayRequest);

Here's the Model

public class NewsModel {

    private String ID;
    private String Title;
    private String ImageURL;
    private String Body;
    private String Lang;



    public NewsModel(){

    }

    public NewsModel(String idd, String title, String imageURL, String body, String lang) {

        this.ID = idd;
        this.Title = title;
        this.ImageURL = imageURL;
        this.Body = body;
        this.Lang = lang;

    }

    public void setID(String ID) {
        this.ID = ID;
    }

    public void setTitle(String title) {
        Title = title;
    }

    public void setBody(String body) {
        Body = body;
    }

    public void setLang(String lang) {
        Lang = lang;
    }

    public String getID() {
        return ID;
    }

    public String getTitle() {
        return Title;
    }

    public void setImageURL(String imageURL) {
        ImageURL = imageURL;
    }

    public String getImageURL() { return ImageURL;}

    public String getBody() {
        return Body;
    }

    public String getLang() {
        return Lang;
    }
}

Here's my current code using GSON

    mRequestQueue = Volley.newRequestQueue(getActivity());


    final ProgressDialog progressDialog = new ProgressDialog(getActivity());
    progressDialog.setMessage("Loading..");
    progressDialog.show();

    final JsonArrayRequest ArrayRequest = new JsonArrayRequest(JsonURL,

            new Response.Listener<JSONArray>() {


                @Override
                public void onResponse(JSONArray response) {

                    NewsModel model;
                    List<NewsModel> modelData;
                    modelData = new ArrayList<>();

                    Gson gson = new Gson();
                    Type listType = new TypeToken<List<NewsModel>>() {}.getType();
                    model = gson.fromJson(response.toString(), listType);
                    modelData.add(model);

                    adapter = new NewsAdapter(modelData, getActivity());
                    recyclerView.setAdapter(adapter);

                    progressDialog.dismiss();
                }
            },

            new Response.ErrorListener() {
                @Override
                 public void onErrorResponse(VolleyError error) {
                    Toast.makeText(getActivity(), "Data Response Error", Toast.LENGTH_SHORT).show();
                }
            }
    );

    mRequestQueue.add(ArrayRequest);

Upvotes: 0

Views: 751

Answers (3)

walkmn
walkmn

Reputation: 2391

1) Add @SerializedName in each field, in your model (NewsModel), like this:

@SerializedName("id") 
private String ID;

@SerializedName("title") 
private String Title;

@SerializedName("thumb") 
private String ImageURL;

@SerializedName("body") 
private String Body;

@SerializedName("lang") 
private String Lang;

2) gson.fromJson(response.toString(), listType); - return list, not single object. You may get list like:

modelData= gson.fromJson(response.toString(), listType); 

Upvotes: 2

snachmsm
snachmsm

Reputation: 19243

I see one problem here:

NewsModel model;
...
Gson gson = new Gson();
Type listType = new TypeToken<List<NewsModel>>() {}.getType();
model = gson.fromJson(response.toString(), listType);
modelData.add(model);

your Type listType is built basing on List<NewsModel>, but using fromJson(...) you are pointing on single NewsModel model

when you are setting type as List then you should get a list from parsed response (assuming JSON is an array), smth like that:

// modelData already an array, NewsModel model not needed at all
modelData= gson.fromJson(response.toString(), listType);  

Upvotes: 2

OneCricketeer
OneCricketeer

Reputation: 191743

You tried to convert a list into a singular object.

Gson gson = new Gson();
// This is a list
Type listType = new TypeToken<List<NewsModel>>() {}.getType();

// This is not a list
NewsModel model = gson.fromJson(response.toString(), listType);

Try assigning modelData = gson.fromJson(response.toString(), listType);

Upvotes: 1

Related Questions