无法使用 Java 的 HttpURLConnection 从 Flickr API 获取结果

Not getting result back from Flickr API using Java's HttpURLConnection

我在查询 Flickr REST API 以搜索照片时遇到问题:

https://www.flickr.com/services/api/explore/flickr.photos.search

我正在 Android 中使用 HttpURLConnection 编写一个小测试 app,我 不想使用任何frameworks(例如OkHttp等)因为这只是简单的学习练习。

我遇到的问题是,虽然 我的 HttpURL 连接 returns 200,但没有 JSON 响应 。但是当我从我的日志中获取构建的 REST URL 时,例如:

https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=API_KEY&tags=basketball&format=json&nojsoncallback=1&api_sig=API_SIG

然后复制粘贴到浏览器,我可以看到正确的JSON。

这是浏览器 returns:

JSON 的片段

{"photos":{"page":1,"pages":2614,"perpage":100,"total":"261380","photo":[{"id":"39168832065","owner":"23023080@N02","secret":"1fb9ee772a","server":"4615","farm":5,"title":"_MG_2714_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"26194325488","owner":"23023080@N02","secret":"3bc00e37ee","server":"4656","farm":5,"title":"_MG_2719_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"39168829925","owner":"23023080@N02","secret":"15580858ce","server":"4695","farm":5,"title":"_MG_2723_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"26194323798","owner":"23023080@N02","secret":"c5e445bd6e","server":"4743","farm":5,"title":"_MG_2727_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"39168828415","owner":"23023080@N02","secret":"89b54b28bc","server":"4648","farm":5,"title":"_MG_2729_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"26194322658","owner":"23023080@N02","secret":"7eff365389","server":"4648","farm":5,"title":"_MG_2732_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"39168826725","owner":"23023080@N02","secret":"2eda660b60","server":"4723","farm":5,"title":"_MG_2734_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"26194321108","owner":"23023080@N02","secret":"0c794e38a8","server":"4765","farm":5,"title":"_MG_2735_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"40034887842","owner":"23023080@N02","secret":"6269997f0f","server":"4755","farm":5,"title":"_MG_2737_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"26194319778","owner":"23023080@N02","secret":"32991c9151","server":"4763","farm":5,"title":"_MG_2739_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"26194319168","owner":"23023080@N02","secret":"4dd5555f5c","server":"4709","farm":5,"title":"_MG_2746_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"40034885802","owner":"23023080@N02","secret":"3f9c5031db","server":"4671","farm":5,"title":"_MG_2747_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"26194317818","owner":"23023080@N02","secret":"e20b503f8f","server":"4668","farm":5,"title":"_MG_2757_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"40067785161","owner":"23023080@N02","secret":"4ab87667fd","server":"4612","farm":5,"title":"_MG_2760_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"40034884132","owner":"23023080@N02","secret":"235b7dc32d","server":"4744","farm":5,"title":"_MG_2762_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"40067784231","owner":"23023080@N02","secret":"0bbae58322","server":"4622","farm":5,"title":"_MG_2763_edit","ispublic":1,"isfriend":0,"isfamily":0},{"id":"40034882942","owner":"23023080@N02","secret":"30345b6b7b","server":"4626","farm":5,"title":"_MG_2764_edit","ispublic":1,"isfriend":0,"isfamily":0},

为什么代码不是 getting/reading 来自连接输入流的 JSON?

package com.bing.ary.xyz;

import android.os.AsyncTask;
import android.util.Log;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.net.ssl.HttpsURLConnection;
import java.net.URL;


public class SearchFlickerAsync extends AsyncTask<String, Void, flikrPhotosResponse> {

        private static final String TAG = "SearchFlickerAsync";

        private String query;

        public SearchFlickerAsync(String query) {
        this.query = query;
        }

    public String getQuery() {
        return query;
        }

        public void setQuery(String query) {
        this.query = query;
        }

    @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected flikrPhotosResponse doInBackground(String... query) {

            Log.i(TAG,"doInBackground(), SearchFlickerAsync input param:"+query);

            HttpsURLConnection httpURLConnection = null;
            flikrPhotosResponse FlikrPhotosResponse = null;
            JsonElement jsonElemnt = null;
            JsonObject jsonObject = null;
            String queryUrl = null;
            StringBuilder queryBuilder = null;

            try {
                //create url string
                queryBuilder = new StringBuilder();
                queryBuilder.append(flickerApi.baseUrl);
                queryBuilder.append(flickerApi.searchFlicker);
                queryBuilder.append(flickerApi.flickrQuery_key + flickerApi.Key);
                queryBuilder.append(flickerApi.flickrQuery_tag);
                queryBuilder.append(this.query);
                queryBuilder.append("&format=json");
                queryBuilder.append("&nojsoncallback=1&api_sig=be97f5275f5a128fbe69dc2cde2560b9");
                //instantiate url for connection
                URL url = new URL(queryBuilder.toString());
                httpURLConnection = (HttpsURLConnection) url.openConnection();
                httpURLConnection.setRequestMethod("GET");
                httpURLConnection.setUseCaches(false);
                httpURLConnection.setAllowUserInteraction(false);
                httpURLConnection.setRequestProperty("Content-length", "0");
                httpURLConnection.connect();
                //no authorization token needed public API httpURLConnection.setRequestProperty("Authorization", "");
                Log.i(TAG,"doInBackground(), http request:"+url.toString());
                int status = httpURLConnection.getResponseCode();

                switch (status) {
                    case 200:
                    case 201:
                        Log.i(TAG,"doInBackground(), http response status:"+status);
                        BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
                        StringBuilder sb = new StringBuilder();
                        String line;
                        while ((line = br.readLine()) != null) {
                            sb.append(line + "\n");
                        }
                        Log.i(TAG,"doInBackground(), http response line:"+line);
                        jsonElemnt = new JsonParser().parse(sb.toString());
                        jsonObject = jsonElemnt.getAsJsonObject();
                        /*Further parse & instantiate FlikrPhotosResponse = */
                        br.close();
                        break;
                    //TODO: ERRORS https://www.flickr.com/services/api/flickr.groups.search.html
                    default:
                        Log.e(TAG,"doInBackground(), http response error status:"+status);
                        //TODO: handle error responses
                        break;

                }



            } catch (IOException ex) {

                ex.printStackTrace();

            } catch (Exception ex) {

                ex.printStackTrace();

            } finally {
                if (httpURLConnection != null) {
                    try {
                        httpURLConnection.disconnect();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }

            return FlikrPhotosResponse;
        }//end doInBackgroud

        protected void onPostExecute(flikrPhotosResponse FlikrPhotosResponse) {

            Log.i(TAG,"onPostExecute(), FlikrPhotosResponse:"+FlikrPhotosResponse);

        }


    }//end class

相关日志无errpr或异常:

02-04 13:24:12.037 3750-4270/com.bing.ary.skywelltest I/SearchFlickerAsync: doInBackground(), http request:https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=37ae86d629a2e4a62917253419cb9e94&tags=basketball&format=json&nojsoncallback=1&api_sig=be97f5275f5a128fbe69dc2cde2560b9
02-04 13:24:12.220 3750-4270/com.bing.ary.skywelltest I/SearchFlickerAsync: doInBackground(), http response status:200
02-04 13:24:12.221 3750-4270/com.bing.ary.skywelltest I/SearchFlickerAsync: doInBackground(), http response line:null

我也

你记录的是错误的东西:

while ((line = br.readLine()) != null) {
    sb.append(line + "\n");
}
Log.i(TAG,"doInBackground(), http response line:"+line);

当然line此时为null。这就是循环终止的原因。您应该记录 sb.toString().

注意:

  1. 您不需要以下任何一项:

    httpURLConnection.setRequestMethod("GET");
    httpURLConnection.setRequestProperty("Content-length", "0");
    httpURLConnection.connect();
    
  2. 您需要使用 HttpsURLConnection 的评论中的许多说法都是不正确的。使用 HttpURLConnection 是完全有效的,即使 URL 是一个 HTTPS,只要你不需要 HttpsURLConnection 的额外方法,因为 HttpsURLConnection 扩展 [=15] =].