为什么JSON文档没有被完全使用? [英] Why is JSON document not fully consumed?

查看:143
本文介绍了为什么JSON文档没有被完全使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从外部来源检索JSON数据以进行练习.我已经准备好了所有代码,但是由于某种原因,我收到一条错误消息,指出该文档没有被完全使用.我已经看过并阅读了多个教程和指南,但似乎仍然无法正确完成.我也在堆栈中搜索了答案,但是由于我不知道出了什么问题,所以我真的不知道要寻找什么.

I'm trying to retrieve JSON data from an external source for practice. I have gotten all the code in place but for some reason I get an error saying that the document is not fully consumed. I have watched and read multiple tutorials and guides, but still can't seem to get it right. I have also searched stack for answers, but since I don't know what's wrong, I don't really know what to look for.

所有代码均已就绪,并且没有明显的错误. JSON数据已经过验证,可以作为原始JSON数据进行检索,如日志中所示.当将数据传输到java数据类时,在Gson转换时会出现问题.有什么想法可能是错的吗?

All the code is in place and there is no obvious fault in it. The JSON data has been validated and it works to retrieve as raw JSON data, as seen in a log. The problem occur at the Gson conversion when the data should be transferred to a java data class. Any ideas what could be wrong?

public class JSONimport extends AsyncTask<Void, Void, DeserializedContainer> {

private static final String TAG = "TAG";

//VARIABLES TO HOLD JSON DATA
private OnLoadListener mListener;


//CONSTRUCTOR
public JSONimport(OnLoadListener listener) {
    this.mListener = listener;
}

//ASYNK, DO IN BACKGROUND THREAD
@Override
protected DeserializedContainer doInBackground(Void... voids) {
    String myJSON = ""; //TEMP VARIABLE TO HOLD JSON DATA
    String completeJSONdata = ""; //VARIABLE TO HOLD COMPLETE JSON DATA

    try {
        URL urlObject = new URL( "https://api.myjson.com/bins/161kkd" );
        HttpURLConnection httpURLConnection = (HttpURLConnection) urlObject.openConnection();
        InputStream inputStreamObject = httpURLConnection.getInputStream();
        BufferedReader bufferedReaderObject = new BufferedReader( new InputStreamReader( inputStreamObject ) );

        while (myJSON != null) {
            myJSON = bufferedReaderObject.readLine();
            completeJSONdata += myJSON;
        }

    } catch (MalformedURLException e) {
        e.printStackTrace();
        Log.d( TAG, "doInBackground: ERROR RETRIEVING URL" );
    } catch (IOException e) {
        e.printStackTrace();
        Log.d( TAG, "doInBackground: ERROR HTTP CONNECTION" );
    }


    //DESERIALIZATION, converting JSON to java variables, making the data easy to handle
    Gson gsonObject = new GsonBuilder()
            .setLenient()
            .create();
    DeserializedContainer deserializedContainerObject;

    deserializedContainerObject = gsonObject.fromJson( completeJSONdata, DeserializedContainer.class );
    //Log.d( TAG, "doInBackground: " + deserializedContainerObject.getDeserializedContainerList() );


    return deserializedContainerObject;
}

@Override
protected void onPostExecute(final DeserializedContainer result) {

    mListener.onSuccess( result );
    //FUNKAR ATT HÄMTA JSON DATA. KOLLA LOGCAT
    Log.d( TAG, "onPostExecuteLOL: " + result );
}

public static interface OnLoadListener {
    void onSuccess(DeserializedContainer container);
}}

错误发生在deserializedContainerObject = gsonObject.fromJson(completeJSONdata,DeserializedContainer.class);

The error is at deserializedContainerObject = gsonObject.fromJson( completeJSONdata, DeserializedContainer.class );

用于保存JSON数据的数据对象:

The data objects to hold the JSON data:

public class DeserializedContainer {
@SerializedName("deserializedContainerList")
public List<DeserializedVariables> deserializedContainerList = new ArrayList<>();

public List<DeserializedVariables> getDeserializedContainerList() {
    return deserializedContainerList;
}}

public class DeserializedVariables {
@SerializedName( "movieName" )
private String movieName;
@SerializedName( "movieYear" )
private int movieYear;
@SerializedName( "movieRating" )
private double movieRating;}

来自主线程的相关数据:

Relevant data from the main thread:

public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";


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

    //BACKGROUND THREAD
    JSONimport jsonImportObject = new JSONimport( new JSONimport.OnLoadListener() {
        @Override
        public void onSuccess(DeserializedContainer container) {
            container.getDeserializedContainerList();
        }
    } );
    jsonImportObject.execute();

    //Log.d( TAG, "onCreateGETTING DATA : " + jsonImportObject.getCompletedData());

    DeserializedContainer deserializedContainerObject = new DeserializedContainer();
    Log.d( TAG, "onCreate: " + deserializedContainerObject);

JSON:

{"deserializedContainerList":[{"movieName":"filmA","movieYear":2017,"movieRating":4.7},{"movieName":"filmB","movieYear":2018,"movieRating": 4.8},{"movieName":"filmC","movieYear":2019,"movieRating":4.9}]}

{"deserializedContainerList":[{"movieName":"filmA","movieYear":2017,"movieRating":4.7},{"movieName":"filmB","movieYear":2018,"movieRating":4.8},{"movieName":"filmC","movieYear":2019,"movieRating":4.9}]}

很长的帖子很抱歉,希望您有足够的精力去做.我真的被卡住了.我知道Retrofit和类似的库,但是我花了很多时间来解决这个问题,所以我还不想放弃它:P

Sorry for such a long post, hope you have the energy to go through it. I'm really stuck. I know of Retrofit and similar libraries, but I have spent so many hours on getting this right that I don't want to abandon it just yet :P

谢谢!

//////// 更新 /////// 我根据Laurent B的建议更新了代码,并成功了!或者,至少它没有崩溃.我尝试使用以下代码在主线程上打印列表:

/////// UPDATE /////// I updated the code according to Laurent B's suggestion, and it worked! Or, at least it didn't crash. I tried printing the list on the main thread with the following code:

for(int i = 0; i < deserializedContainerObject.deserializedContainerList.size(); i++) {
        Log.d( TAG, "onCreate: " + deserializedContainerObject.deserializedContainerList.get( i ));

    }

但是什么也没显示.当检查deserializedContainerObject.deserializedContainerList.size()时,它显示为0.也就是说,没有数据添加到列表中.至少它不会崩溃,这要归功于Laurent B,因此更近了一步.

But nothing showed. When checking deserializedContainerObject.deserializedContainerList.size() it showed 0. That is, no data has been added to the list... Hmmm. At least it doesn't crash, thanks to Laurent B so one step closer.

推荐答案

正在传递值,但是null也随之传递,因此请使用if语句,而不要使用while 像这样.

The value is being pass, but however null is also getting passed with it so use an if statement rather than using while like this..

if (myJSON != null) {
                myJSON = bufferedReaderObject.readLine();
                completeJSONdata += myJSON;
            }

然后像这样在Gson中进行转换.

then convert in Gson like this..

    Gson gson = new Gson();
    deserializedContainerObject = gson.fromJson(completeJSONdata, DeserializedContainer.class);

DeserializedVariables类中编写吸气剂和吸气剂

write the getters and setters in DeserializedVariables class

public String getMovieName() {
         return movieName;
     }

     public void setMovieName(String movieName) {
         this.movieName = movieName;
     }

     public Integer getMovieYear() {
         return movieYear;
     }

     public void setMovieYear(Integer movieYear) {
         this.movieYear = movieYear;
     }

     public Double getMovieRating() {
         return movieRating;
     }

     public void setMovieRating(Double movieRating) {
         this.movieRating = movieRating;
     }

现在您可以像这样在onPostExecute()中检索它.

And now you can retrieve it in your onPostExecute() like this..

@Override
    protected void onPostExecute( DeserializedContainer result) {

        mListener.onSuccess( result );

        for (int i = 0; i <result.deserializedContainerList.size(); i++) {
            DeserializedVariables deserializedVariables = result.deserializedContainerList.get(i);
            Log.d( TAG, "onPostExecuss: " + deserializedVariables.getMovieName() );
        }

    }

这篇关于为什么JSON文档没有被完全使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆