为什么没有完全使用JSON文档?

时间:2018-01-18 13:19:24

标签: java android json network-programming gson

我试图从外部源检索JSON数据以进行练习。我已经获得了所有代码但由于某种原因我得到一个错误,说文档没有完全消耗。我已经观看并阅读了多个教程和指南,但似乎仍然无法做到正确。我也搜索了堆栈的答案,但由于我不知道错误的原因,我真的不知道该找什么。

所有代码都已到位,并且没有明显的错误。 JSON数据已经过验证,它可以检索为原始JSON数据,如日志中所示。当数据应该传输到java数据类时,在Gson转换时会出现问题。什么想法可能是错的?

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);

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

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;}

主线程的相关数据:

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:

{&#34; deserializedContainerList&#34;:[{&#34;的movieName&#34;:&#34; filmA&#34;&#34; movieYear&#34;:2017,&#34; movieRating&# 34;:4.7},{&#34;的movieName&#34;:&#34; filmB&#34;&#34; movieYear&#34;:2018,&#34; movieRating&#34;:4.8},{& #34;的movieName&#34;:&#34; filmC&#34;&#34; movieYear&#34;:2019,&#34; movieRating&#34;:4.9}]}

很抱歉这么长的帖子,希望你有能量通过它。我真的卡住了。我知道Retrofit和类似的库,但是我已经花了这么多时间才能做到这一点,我还是不想放弃它:P

谢谢!

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

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

    }

但没有表现出来。当检查deserializedContainerObject.deserializedContainerList.size()时,它显示为0.也就是说,没有数据添加到列表中...嗯。至少它并没有崩溃,感谢Laurent B更近了一步。

2 个答案:

答案 0 :(得分:1)

你的completeJSONdata不正确,因为你总是把&#34; null&#34;走到尽头。

相反,你的while子句应该是例如:

$.ajax({
    type: "POST",
    //if u have the js functions on another file (not in your view)
    //u can create a variable on the header like var baseUrl = <?=base_url()?>
    //and url would be like: baseUrl + 'MyController/myFunction'
    url: "<?php echo base_url();?>MyController/myFunction",
    dataType : 'json',
    success :function(data) {
        alert(data.first_name);
    }
 });

顺便说一句,不要忘记关闭你的溪流,例如尝试使用:

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

答案 1 :(得分:1)

该值正在传递,但是null也会随之传递,因此请使用if语句而不是while 喜欢这个..

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

然后像这样转换为Gson ..

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

DeserializedVariables

中编写getter和setter
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()中找回它..

@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() );
        }

    }