জিএসএন "প্রত্যাশিত BEGIN_OBJECT তবে BEGIN_ARRAY" ছুঁড়েছিল?


295

আমি এই জাতীয় মত একটি JSON স্ট্রিং পার্স করার চেষ্টা করছি

[
   {
      "updated_at":"2012-03-02 21:06:01",
      "fetched_at":"2012-03-02 21:28:37.728840",
      "description":null,
      "language":null,
      "title":"JOHN",
      "url":"http://rus.JOHN.JOHN/rss.php",
      "icon_url":null,
      "logo_url":null,
      "id":"4f4791da203d0c2d76000035",
      "modified":"2012-03-02 23:28:58.840076"
   },
   {
      "updated_at":"2012-03-02 14:07:44",
      "fetched_at":"2012-03-02 21:28:37.033108",
      "description":null,
      "language":null,
      "title":"PETER",
      "url":"http://PETER.PETER.lv/rss.php",
      "icon_url":null,
      "logo_url":null,
      "id":"4f476f61203d0c2d89000253",
      "modified":"2012-03-02 23:28:57.928001"
   }
]

বস্তুর তালিকায়।

List<ChannelSearchEnum> lcs = (List<ChannelSearchEnum>) new Gson().fromJson( jstring , ChannelSearchEnum.class);

এখানে আমি ব্যবহার করছি একটি অবজেক্ট ক্লাস।

import com.google.gson.annotations.SerializedName;

public class ChannelSearchEnum {



@SerializedName("updated_at")
private String updated_at;

@SerializedName("fetched_at")
private String fetched_at;

@SerializedName("description")
private String description;

@SerializedName("language")
private String language;

@SerializedName("title")
private String title;

@SerializedName("url")
private String url;

@SerializedName("icon_url")
private String icon_url;

@SerializedName("logo_url")
private String logo_url;

@SerializedName("id")
private String id;

@SerializedName("modified")
private String modified;

public final String get_Updated_at() {
    return this.updated_at;
}

public final String get_Fetched_at() {
    return this.fetched_at;
}

public final String get_Description() {
    return this.description;
}

public final String get_Language() {
    return this.language;
}

public final String get_Title() {
    return this.title;
}

public final String get_Url() {
    return this.url;
}

public final String get_Icon_url() {
    return this.icon_url;
}

public final String get_Logo_url() {
    return this.logo_url;
}

public final String get_Id() {
    return this.id;
}

public final String get_Modified() {
    return this.modified;
}

        }

তবে এটি আমাকে ছুঁড়ে দেয়

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2

কোন ধারণা আমি কীভাবে এটি ঠিক করব?


12
@ সনি - এটি ভুল। আপনি যদি jsonlint.org এ যান এবং তাঁর JSON অনুলিপি / পেস্ট করেন তবে দেখবেন যে এটি বৈধ।
ব্রায়ান রোচ

@ সনি - না, "[" এবং "]" সরানো হয়েছে, কিন্তু এখনও একই the অনুমান করুন এটি আরও বেশি হতে পারে কারণ আমার কাছে থাকা স্ট্রিংয়ে কেবল একটি নয়, একাধিক অবজেক্ট রয়েছে।
রজার ট্র্যাভিস

আপনি আপনার jstringকোডটিতে ইঙ্গিত করেছেন এমন দেখতে আপনার চেহারাটি কী ?
ইগোরগানাপলস্কি

আমি মনে করি একটি পর্যবেক্ষণ, যখন প্রতিক্রিয়া অ্যারে ফিরে আসে তখন তালিকায় নেওয়ার চেষ্টা করুন, এটি আমার সমস্যার সমাধান করে।
iamkdblue

উত্তর:


331

সমস্যাটি হচ্ছে আপনি বলছেন যে Gsonআপনার ধরণের একটি অবজেক্ট রয়েছে। আপনি না। আপনার ধরণের জিনিসগুলির একটি অ্যারে রয়েছে। আপনি কেবল ফলাফলটি চেষ্টা করে দেখতে পাচ্ছেন না এবং এটি যাদুবিদ্যার দ্বারা কাজ করার আশা করতে পারেন;)

এর জন্য ব্যবহারকারী নির্দেশিকা Gsonকীভাবে এটি মোকাবেলা করবেন তা ব্যাখ্যা করে:

https://github.com/google/gson/blob/master/UserGuide.md

এটি কাজ করবে:

ChannelSearchEnum[] enums = gson.fromJson(yourJson, ChannelSearchEnum[].class);

তবে এটি আরও ভাল:

Type collectionType = new TypeToken<Collection<ChannelSearchEnum>>(){}.getType();
Collection<ChannelSearchEnum> enums = gson.fromJson(yourJson, collectionType);

সম্ভবত সত্যই। অবজেক্টের অ্যারে হিসাবে, টাইপটি রানটাইমের সময় ধরে রাখা হয় তাই জিএসন কী কী সন্ধান করবে তা জানে। ভাল ধারণা.
njzk2

3
+1 এর জন্য TypoToken<Collection<Something>>- যখন আপনার সংগ্রহ (সাবক্লাস) এবং / অথবা আইটারেবলস থাকতে পারে তখন অ্যারে ব্যবহার করবেন না।
ফিলিপ রেচার্ট

আপনি কি মনে করেন নির্বাচিত অবজেক্ট / অ্যারে পার্স করা সঠিক পদ্ধতি? সাহায্যের stackoverflow.com/questions/18140830/...
LOG_TAG

1
যদি আমরা স্ট্রিং দিয়ে এটি তৈরি করতে চাই; উদাহরণস্বরূপ আমি স্ট্রিং [] t = gson.fromJson (myJson, স্ট্রিং []। শ্রেণি) এর মতো কিছু লিখতে পারি
সাহিন ইয়ানলিক

4
এই উত্তর অনুভব করা অসম্পূর্ণ !!
ইঞ্জিনসেন্স

45

সমস্যাটি হ'ল আপনি কোনও ধরণের অবজেক্টের জন্য জিজ্ঞাসা করছেন ChannelSearchEnumতবে যা আপনার কাছে রয়েছে তা হ'ল একটি ধরণের একটি অবজেক্ট List<ChannelSearchEnum>

আপনি এটি দিয়ে এটি অর্জন করতে পারেন:

Type collectionType = new TypeToken<List<ChannelSearchEnum>>(){}.getType();
List<ChannelSearchEnum> lcs = (List<ChannelSearchEnum>) new Gson()
               .fromJson( jstring , collectionType);

1
এটা কি ধরণের Type? কী আমদানি করব?
স্ম্যাথহেনগ্লিশ

4
@ এস ম্যাটহে_আঙ্গলিশ সম্ভবতjava.lang.reflect.Type
গিলিয়াম পোলেট

36

আমার ক্ষেত্রে JSON স্ট্রিং:

[{"category":"College Affordability",
  "uid":"150151",
  "body":"Ended more than $60 billion in wasteful subsidies for big banks and used the savings to put the cost of college within reach for more families.",
  "url":"http:\/\/www.whitehouse.gov\/economy\/middle-class\/helping middle-class-families-pay-for-college",
  "url_title":"ending subsidies for student loan lenders",
  "type":"Progress",
  "path":"node\/150385"}]

এবং আমি রিসাইক্যভিউতে "বিভাগ" এবং "url_title" মুদ্রণ করি

Datum.class

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Datum {
@SerializedName("category")
@Expose
private String category;
@SerializedName("uid")
@Expose
private String uid;
@SerializedName("url_title")
@Expose
private String urlTitle;

/**
 * @return The category
 */
public String getCategory() {
    return category;
}

/**
 * @param category The category
 */
public void setCategory(String category) {
    this.category = category;
}

/**
 * @return The uid
 */
public String getUid() {
    return uid;
}

/**
 * @param uid The uid
 */
public void setUid(String uid) {
    this.uid = uid;
}

/**
 * @return The urlTitle
 */
public String getUrlTitle() {
    return urlTitle;
}

/**
 * @param urlTitle The url_title
 */
public void setUrlTitle(String urlTitle) {
    this.urlTitle = urlTitle;
}

}

RequestInterface

import java.util.List;

import retrofit2.Call;
import retrofit2.http.GET;

/**
 * Created by Shweta.Chauhan on 13/07/16.
 */

public interface RequestInterface {

   @GET("facts/json/progress/all")
   Call<List<Datum>> getJSON();
}

DataAdapter

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

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

/**
 * Created by Shweta.Chauhan on 13/07/16.
 */

public class DataAdapter extends RecyclerView.Adapter<DataAdapter.MyViewHolder>{

private Context context;
private List<Datum> dataList;

public DataAdapter(Context context, List<Datum> dataList) {
    this.context = context;
    this.dataList = dataList;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.data,parent,false);
    return new MyViewHolder(view);
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    holder.categoryTV.setText(dataList.get(position).getCategory());
    holder.urltitleTV.setText(dataList.get(position).getUrlTitle());

}

@Override
public int getItemCount() {
    return dataList.size();
}

public class MyViewHolder extends RecyclerView.ViewHolder{

    public TextView categoryTV, urltitleTV;

    public MyViewHolder(View itemView) {
        super(itemView);
        categoryTV = (TextView) itemView.findViewById(R.id.txt_category);
        urltitleTV = (TextView)     itemView.findViewById(R.id.txt_urltitle);
    }
}
}

এবং অবশেষে MainActivity.java

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class MainActivity extends AppCompatActivity {

private RecyclerView recyclerView;
private DataAdapter dataAdapter;
private List<Datum> dataArrayList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initViews();
}

private void initViews(){
    recyclerView=(RecyclerView) findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
    loadJSON();
}

private void loadJSON(){
    dataArrayList = new ArrayList<>();
    Retrofit retrofit=new Retrofit.Builder().baseUrl("https://www.whitehouse.gov/").addConverterFactory(GsonConverterFactory.create()).build();
    RequestInterface requestInterface=retrofit.create(RequestInterface.class);
    Call<List<Datum>> call= requestInterface.getJSON();
    call.enqueue(new Callback<List<Datum>>() {
        @Override
        public void onResponse(Call<List<Datum>> call, Response<List<Datum>> response) {
            dataArrayList = response.body();
            dataAdapter=new DataAdapter(getApplicationContext(),dataArrayList);
            recyclerView.setAdapter(dataAdapter);
        }

        @Override
        public void onFailure(Call<List<Datum>> call, Throwable t) {
            Log.e("Error",t.getMessage());
        }
    });
}
}

5
এই জাতীয় সমস্যার জন্য সেরা উত্তর
নিকি মানালি

4
বিশেষত retrofit ব্যবহারকারীদের জন্য এটি পুরোপুরি প্রশ্নের উত্তর দেয়। যে কেউ স্পষ্টতা চায়, তার জন্য আপনার যে অংশটি সবচেয়ে বেশি প্রয়োজন তা হ'ল কল <লিস্ট <দ্যাটাম>> getJSON ();
কার্লোস আয়নোনা 21 '

13

বিকল্প হতে পারে

আপনার প্রতিক্রিয়া মত চেহারা করতে

myCustom_JSONResponse

{"master":[
   {
      "updated_at":"2012-03-02 21:06:01",
      "fetched_at":"2012-03-02 21:28:37.728840",
      "description":null,
      "language":null,
      "title":"JOHN",
      "url":"http://rus.JOHN.JOHN/rss.php",
      "icon_url":null,
      "logo_url":null,
      "id":"4f4791da203d0c2d76000035",
      "modified":"2012-03-02 23:28:58.840076"
   },
   {
      "updated_at":"2012-03-02 14:07:44",
      "fetched_at":"2012-03-02 21:28:37.033108",
      "description":null,
      "language":null,
      "title":"PETER",
      "url":"http://PETER.PETER.lv/rss.php",
      "icon_url":null,
      "logo_url":null,
      "id":"4f476f61203d0c2d89000253",
      "modified":"2012-03-02 23:28:57.928001"
   }
]
}

পরিবর্তে

server_JSONResponse

[
   {
      "updated_at":"2012-03-02 21:06:01",
      "fetched_at":"2012-03-02 21:28:37.728840",
      "description":null,
      "language":null,
      "title":"JOHN",
      "url":"http://rus.JOHN.JOHN/rss.php",
      "icon_url":null,
      "logo_url":null,
      "id":"4f4791da203d0c2d76000035",
      "modified":"2012-03-02 23:28:58.840076"
   },
   {
      "updated_at":"2012-03-02 14:07:44",
      "fetched_at":"2012-03-02 21:28:37.033108",
      "description":null,
      "language":null,
      "title":"PETER",
      "url":"http://PETER.PETER.lv/rss.php",
      "icon_url":null,
      "logo_url":null,
      "id":"4f476f61203d0c2d89000253",
      "modified":"2012-03-02 23:28:57.928001"
   }
]

কোড

  String server_JSONResponse =.... // the string in which you are getting your JSON Response after hitting URL
String myCustom_JSONResponse="";// in which we will keep our response after adding object element to it
     MyClass apiResponse = new MyClass();

     myCustom_JSONResponse="{\"master\":"+server_JSONResponse+"}";



    apiResponse = gson.fromJson(myCustom_JSONResponse, MyClass .class);

এটির পরে এটি অন্য কোনওটি হবে GSON Parsing


আমি যদি আমার জসন ফর্ম্যাটটি পরিবর্তন করতে না পারি তবে কী হবে? আমি আমার মডেল ক্লাস সেট করার জন্য ভলির জিসন অনুরোধটি ব্যবহার করছি। এটা কিভাবে করতে হবে? ধন্যবাদ
কবিশ কানওয়াল

@ কাভিশকানওয়াল এই থ্রেডে প্রদত্ত অন্যান্য সমাধানগুলি চেষ্টা করুন, এ ছাড়া আমার কোনও ধারণা নেই
ডেল্টা ক্যাপ ০১৯

8

GSON ব্যবহারকারী গাইড অনুসারে , আপনি পারবেন না।

সংগ্রহ সীমাবদ্ধতা

স্বেচ্ছাসেবী অবজেক্টগুলির সংগ্রহকে সিরিয়ালাইজ করতে পারে তবে এটি থেকে ডিসরিয়ালাইজ করতে পারে না। কারণ ফলাফলকারী সামগ্রীর ধরণটি ব্যবহারকারীকে বোঝানোর কোনও উপায় নেই


7
তাঁর কাছে স্বেচ্ছাচারিত বস্তুগুলির সংগ্রহ নেই, তাঁর একটি নির্দিষ্ট ধরণের অবজেক্টের সংকলন রয়েছে যা Gsonআনন্দের সাথে মোকাবেলা করবে
ব্রায়ান রোচ

প্রকৃতপক্ষে, টাইপটোকেনের সাথে আমি যেমন উত্তরটি লিখেছিলাম ঠিক তেমনই লিখেছিলাম, তবে যেহেতু জেনেরিক টাইপটি রানটাইমটিতে এম্বেড করা হয়নি তাই আমি কীভাবে এটি সম্ভবত কাজ করতে পারি তা দেখিনি। (যদিও আমি এটি পরীক্ষা করে দেখিনি)।
njzk2

3

এটি কোনও জসন অ্যারের তালিকার মতো দেখাচ্ছে fore ArrayListতাই ডেটা পরিচালনা করার জন্য এটি সর্বোত্তম । আপনার এপিআই শেষ পয়েন্ট এ অ্যারের তালিকা যুক্ত করুন

 @GET("places/")
Call<ArrayList<Place>> getNearbyPlaces(@Query("latitude") String latitude, @Query("longitude") String longitude);

1

নীচে আপনার জবাবের অতিরিক্ত ধরণের গসনকে আপনাকে জানাতে হবে

import com.google.common.reflect.TypeToken;
import java.lang.reflect.Type;


Type collectionType = new TypeToken<List<UserSite>>(){}.getType();
List<UserSite> userSites  = gson.fromJson( response.getBody() , collectionType);

1

আমি নিশ্চিত নই যে এটি জিএসএন ব্যবহারের সর্বোত্তম উপায়, তবে আমার পক্ষে কাজ করে। আপনি এর মতো কিছু ব্যবহার করতে পারেন MainActivity:

 public void readJson() {
    dataArrayList = new ArrayList<>();
    String json = "[\n" + IOHelper.getData(this) + "\n]\n";
    Log.d(TAG, json);
    try{
        JSONArray channelSearchEnums = new JSONArray(json);

        for(int i=0; i< channelSearchEnums.length(); i++)
        {
            JSONObject enum = channelSearchEnums.getJSONObject(i);
            ChannelSearchEnum channel = new ChannelSearchEnum(
                   enum.getString("updated_at"), enum.getString("fetched_at"),
                   enum.getString("description"), enum.getString("language"),
                   enum.getString("title"), enum.getString("url"),
                   enum.getString("icon_url"), enum.getString("logo_url"),
                   enum.getString("id"), enum.getString("modified"))         

                   dataArrayList.add(channel);
        }

         //The code and place you want to show your data            

    }catch (Exception e)
    {
        Log.d(TAG, e.getLocalizedMessage());
    }
}

আপনার কাছে কেবল স্ট্রিং রয়েছে, তবে আপনার যদি দ্বিগুণ বা ইনট থাকে তবে আপনি রাখতে পারেন getDoubleবা getIntখুব বেশি করতে পারেন ।

IOHelperশ্রেণীর পদ্ধতিটি পরেরটি (এখানে, অভ্যন্তরীণ সঞ্চয়স্থানে পাথটি সংরক্ষণ করা হবে):

 public static String getData(Context context) {
    try {
        File f = new File(context.getFilesDir().getPath() + "/" + fileName);
        //check whether file exists
        FileInputStream is = new FileInputStream(f);
        int size = is.available();
        byte[] buffer = new byte[size];
        is.read(buffer);
        is.close();
        return new String(buffer);
    } catch (IOException e) {
        Log.e("TAG", "Error in Reading: " + e.getLocalizedMessage());
        return null;
    }
}

আপনি যদি এই সম্পর্কে আরও তথ্য চান, আপনি এই ভিডিওটি দেখতে পারেন , যেখানে আমি কোড পেয়েছি readJson(); এবং এই থ্রেড যেখানে আমি কোড পাই getData()


0

Kotlin:

var list=ArrayList<Your class name>()
val listresult: Array<YOUR CLASS NAME> = Gson().fromJson(
                YOUR JSON RESPONSE IN STRING,
                Array<Your class name>:: class.java)

list.addAll(listresult)

@ শ্র্রেডেটর সম্ভবত আমি উত্তরণের পিছনে কারণ জানতে পারি know
অভয় কুমার ভূমিহার

আমি কোনও কিছুকে উত্সাহিত বা হ্রাস করিনি, কেবল সম্পাদিত।
শ্রাদী
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.