代码之家  ›  专栏  ›  技术社区  ›  Joakim Sjöstedt

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

  •  7
  • Joakim Sjöstedt  · 技术社区  · 8 年前

    我正在尝试从外部源检索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);
    }}
    

    错误位于反序列化的ContainerObject=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:

    {“反序列化内容列表”:[{“movieName”:“filmA”,“movieYear”:2017,“movieRating”:4.7},{“movieName”:“filmB”,“movieYear”:2018,“movieRating”:4.8},{“movieName”:“filmC”,“movieYear”:2019,“movieRating”:4.9}]}

    很抱歉发了这么长的帖子,希望你有精力去看。我真的卡住了。我知道有改装和类似的库,但我花了这么多时间来解决这个问题,我现在还不想放弃它:P

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

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

    但什么都没显示出来。检查反序列化ContainerObject时。反序列化ContainerList。size()显示为0。也就是说,没有数据添加到列表中。。。嗯,至少它没有崩溃,多亏了劳伦特B,所以更近了一步。

    2 回复  |  直到 8 年前
        1
  •  1
  •   Vikas singh    8 年前

    正在传递值,但同时也传递null,因此请使用if语句,而不是使用while 这样地。。

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

    然后像这样在Gson中转换。。

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

    将getter和setter写入 DeserializedVariables

    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() );
            }
    
        }
    
        2
  •  1
  •   Laurent B    8 年前

    您的completeJSONdata不正确,因为您总是在末尾加上“null”。

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

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

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

    try (InputStream inputStreamObject = httpURLConnection.getInputStream()) {
    // ...
    }