从HTTP响应中获取JSON对象

102

我想从一个 Http get 响应中获取一个 JSON 对象:

这是我当前的 Http get 代码:

protected String doInBackground(String... params) {

    HttpClient client = new DefaultHttpClient();
    HttpGet request = new HttpGet(params[0]);
    HttpResponse response;
    String result = null;
    try {
        response = client.execute(request);         
        HttpEntity entity = response.getEntity();

        if (entity != null) {

            // A Simple JSON Response Read
            InputStream instream = entity.getContent();
            result = convertStreamToString(instream);
            // now you have the string representation of the HTML request
            System.out.println("RESPONSE: " + result);
            instream.close();
            if (response.getStatusLine().getStatusCode() == 200) {
                netState.setLogginDone(true);
            }

        }
        // Headers
        org.apache.http.Header[] headers = response.getAllHeaders();
        for (int i = 0; i < headers.length; i++) {
            System.out.println(headers[i]);
        }
    } catch (ClientProtocolException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    return result;
}

这里是convertStreamToString函数:

private static String convertStreamToString(InputStream is) {

    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();

    String line = null;
    try {
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return sb.toString();
}

现在我只是得到一个字符串对象。如何将其转换为 JSON 对象?


1
你在你的结果字符串里得到了什么? - R4chi7
你为什么要两次使用 response.getEntity()? - R4chi7
获取JSON对象时,您连接的Web服务器不应该返回一个JSON吗?它是否这样做? - rockstar
@Zapnologica,请检查我的答案。还请看agen451的答案。 - rockstar
10个回答

79

你得到的字符串只是JSON Object.toString()。这意味着你获得了JSON对象,但是以字符串格式。

如果你应该获得JSON对象,你可以直接输入:

JSONObject myObject = new JSONObject(result);

如果在 HttpExchange 的情况下会怎样呢? - Hema
@Renan Bandeira 我正在尝试使用您的代码将我的HTTP响应转换为JSON对象,但是我遇到了以下错误:Error:(47, 50) java: incompatible types: java.lang.StringBuffer cannot be converted to java.util.Map - Christos Karapapas
@Karapapas,你能展示一下你的代码吗?我的回答是在2013年。我建议你使用Retrofit和Gson/Jackson来处理请求和Json序列化。 - Renan Bandeira
我该如何用C#完成这个相同的作业? - Farrukh Sarmad

13

执行以下操作以获取 JSON

String json = EntityUtils.toString(response.getEntity());

更多细节请参考:从HttpResponse获取JSON


40
那是一个字符串,不是JSON! - Francisco Corrales Morales
8
为什么这个帖子会有那么多赞?这只是一个toString()函数,基本上和原贴作者所做的完全一样。 - cst1992
1
至少这样可以消除很多 OP 的低级开销代码。请参见下面 @Catalin Pirvu 的帖子,以获取更完整的解决方案。 - Cesar

12

这不是你问题的确切答案,但这可能会对你有所帮助

public class JsonParser {

    private static DefaultHttpClient httpClient = ConnectionManager.getClient();

    public static List<Club> getNearestClubs(double lat, double lon) {
        // YOUR URL GOES HERE
        String getUrl = Constants.BASE_URL + String.format("getClosestClubs?lat=%f&lon=%f", lat, lon);

        List<Club> ret = new ArrayList<Club>();

        HttpResponse response = null;
        HttpGet getMethod = new HttpGet(getUrl);
        try {
            response = httpClient.execute(getMethod);

            // CONVERT RESPONSE TO STRING
            String result = EntityUtils.toString(response.getEntity());

            // CONVERT RESPONSE STRING TO JSON ARRAY
            JSONArray ja = new JSONArray(result);

            // ITERATE THROUGH AND RETRIEVE CLUB FIELDS
            int n = ja.length();
            for (int i = 0; i < n; i++) {
                // GET INDIVIDUAL JSON OBJECT FROM JSON ARRAY
                JSONObject jo = ja.getJSONObject(i);

                // RETRIEVE EACH JSON OBJECT'S FIELDS
                long id = jo.getLong("id");
                String name = jo.getString("name");
                String address = jo.getString("address");
                String country = jo.getString("country");
                String zip = jo.getString("zip");
                double clat = jo.getDouble("lat");
                double clon = jo.getDouble("lon");
                String url = jo.getString("url");
                String number = jo.getString("number");

                // CONVERT DATA FIELDS TO CLUB OBJECT
                Club c = new Club(id, name, address, country, zip, clat, clon, url, number);
                ret.add(c);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // RETURN LIST OF CLUBS
        return ret;
    }

}
Again, it’s relatively straight forward, but the methods I’ll make special note of are:

JSONArray ja = new JSONArray(result);
JSONObject jo = ja.getJSONObject(i);
long id = jo.getLong("id");
String name = jo.getString("name");
double clat = jo.getDouble("lat");

10

如果没有查看您的JSON输出,很难为您提供可用的代码。这个教程非常有用,但您可以使用以下内容:

JSONObject jsonObj = new JSONObject("yourJsonString");

然后您可以使用以下方式从此JSON对象中检索:

String value = jsonObj.getString("yourKey");

1
非常好的教程。 "通常,所有JSON节点都以方括号或花括号开头。 [和{之间的区别是,方括号([)表示JSONArray节点的开始,而花括号({)表示JSONObject。因此,在访问这些节点时,我们需要调用适当的方法来访问数据。如果您的JSON节点以[开头,则应使用getJSONArray()方法。同样,如果节点以{开头,则应使用getJSONObject()方法。" - another

6
为了解决这个问题,如果你需要一个`JSONObject`,首先需要从`result`中获取一个`String`:
String jsonString = EntityUtils.toString(response.getEntity());

接下来你可以获取你的JSONObject

JSONObject jsonObject = new JSONObject(jsonString);

4
您需要像下面这样使用JSONObject:
String mJsonString = downloadFileFromInternet(urls[0]);

JSONObject jObject = null;
try {
    jObject = new JSONObject(mJsonString);
} 
catch (JSONException e) {
    e.printStackTrace();
    return false;
}

...

private String downloadFileFromInternet(String url)
{
    if(url == null /*|| url.isEmpty() == true*/)
        new IllegalArgumentException("url is empty/null");
    StringBuilder sb = new StringBuilder();
    InputStream inStream = null;
    try
    {
        url = urlEncode(url);
        URL link = new URL(url);
        inStream = link.openStream();
        int i;
        int total = 0;
        byte[] buffer = new byte[8 * 1024];
        while((i=inStream.read(buffer)) != -1)
        {
            if(total >= (1024 * 1024))
            {
                return "";
            }
            total += i;
            sb.append(new String(buffer,0,i));
        }
    }
    catch(Exception e )
    {
        e.printStackTrace();
        return null;
    }catch(OutOfMemoryError e)
    {
        e.printStackTrace();
        return null;
    }
    return sb.toString();
}

private String urlEncode(String url)
{
    if(url == null /*|| url.isEmpty() == true*/)
        return null;
    url = url.replace("[","");
    url = url.replace("]","");
    url = url.replaceAll(" ","%20");
    return url;
}

希望这能帮助你。

嗨Apnologica..如果任何答案满足了您的需求,请接受它,以便让其他人更容易找到正确的答案。谢谢 - Sushil

1

1) 将响应实体转换为字符串:String jsonString = EntityUtils.toString(response.getEntity()); 2) 创建一个 JSON 对象:JSONObject jsonObject = new JSONObject(jsonString);


1
目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

0
如果你的API返回值是Java对象,那么你从Outputstream获取的字符串应该是JSON格式的字符串,例如:
{\"name\":\"xyz\", \"age\":21}

这段代码可以通过多种方式将其转换为JSON对象,其中一种方法是使用Google的GSON库。

GsonBuilder builder = new GsonBuilder().setPrettyPrinting(); Gson gson = builder.create(); <javaobject> = gson.fromJson(<outputString>, <Classofobject>.class);

0

一个人可以使用Jackson而不是Gson,它实现了Json Tree Model。

ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(responseString);

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接