在Android中发送和解析JSON对象


137

我想以JSON对象的形式将消息发送到服务器,并解析来自服务器的JSON响应。

JSON对象的示例

{
  "post": {
    "username": "John Doe",
    "message": "test message",
    "image": "image url",
    "time":  "current time"
  }
}

我试图通过逐个属性手动解析JSON。我可以使用任何库/实用工具来简化此过程吗?


2
该网址不再可用...您可以更新它吗?
Cipi

1
这是一个详细的示例:Android – JSON解析示例
Paresh Mayani

1
@ Paresh Mayani&@ primpap ..我知道我们可以使用从get方法接收到的来自服务器的JSON来填充服务器中的数据,我对此很满意....但是如果我们使用post方法将数据发送到服务器,请执行我们再次将数据作为JSON发送,我指的是primpap报价问题“我想将JSON对象形式的消息发送到Django服务器” .....我在服务器上使用Mysql ....或我发送JSON对象?...您可以向我澄清此信息吗?...还是任何帮助我了解该概念的链接都将有所帮助,谢谢
Devrath

Answers:


118

我很惊讶这些没有被提及:但是,与使用json.org的小程序包进行简单的手工操作相比,GSon和Jackson更为方便。所以:

因此,您实际上可以绑定到自己的POJO,而不是绑定到某些半确定的树节点或列表和地图。(至少杰克逊也允许绑定到这些东西(也许还有GSON,也不确定),如果您真的想要这些而不是“真实的”对象,则可以使用JsonNode,Map,List。

编辑2014年3月19日:

另一个新的竞争者是Jackson jr库:它使用与Jackson(jackson-core)相同的快速流解析器/生成器,但是数据绑定部分很小(50kB)。功能受到更多限制(没有注释,只有常规的Java Bean),但是性能方面应该很快,并且初始化(首次调用)开销也非常低。因此,这可能是个不错的选择,尤其是对于较小的应用程序。


10
为GSON +1。我们已经特意使用GSON的流支持 sites.google.com/site/gson/streaming在我们的Android应用。
2011年

FWIW,Jackson还具有流API:wiki.fasterxml.com/JacksonStreamingApi
StaxMan

2
同时为GSON流式传输+1。首先实现了Jackson流,但尽管在调试版本中起作用,但ProGuard产生了大量错误,而发行版则导致崩溃,很难跟踪。我确定这不是与Jackson相关的问题,但是这使我切换到GSON,效果很好,仅需要额外的14kB即可进行流式传输。
sven 2011年

对于愚蠢的无法预料的json混合字符串并列出ex:[“ toto”,“ tata”,[“ monty”,[“ tor”,“ python”]]]?(某种需要递归函数才能使用它的数据结构)
christophe31,2014年

85

您可以使用org.json.JSONObjectorg.json.JSONTokener。您不需要任何外部库,因为这些类是Android SDK附带的


糟糕!我错过了。实际上,它们是网站上的org.json库。
Gaurav Vaish

这就是我所使用的,它就像一种魅力。
亚当

如果可以给出一个示例或指向该示例的链接,那就太好了。这样更容易学习。:)
Primal Pappachan


1
更加方便,编写更少的代码:一两行而不是几十行。
StaxMan 2010年

31

如果数据具有确定的结构,则GSON最容易使用,而且走的路也很简单。

下载gson

将其添加到引用的库。

package com.tut.JSON;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class SimpleJson extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        String jString = "{\"username\": \"tom\", \"message\": \"roger that\"}  ";


        GsonBuilder gsonb = new GsonBuilder();
        Gson gson = gsonb.create();
        Post pst;

        try {
            pst = gson.fromJson(jString,  Post.class);

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

邮编代码

package com.tut.JSON;

public class Post {

    String message;
    String time;
    String username;
    Bitmap icon;
}

4
就其价值而言,可以简化代码:不需要JSONObject转换。sson和getter对于GSon是可选的;如果需要,可以添加,但并非绝对必要。
StaxMan 2010年

4
只是为了澄清StaxMan的评论。您的示例使用jString,将其转换为JSONObject,然后将其转换回String,以供gson读取。只需使用pst = gson.fromJson(jString,Post.class)。我相信这也将摆脱对try-catch的需求。正如StaxMan所指出的那样,Post.class中的setter和getter没有任何价值。纠正您的示例对其他人会有所帮助。
Matt

我从答案中删除了双转换部分
Whlk,2012年

4

这是JsonParser类

public class JSONParser {

    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";

    // constructor
    public JSONParser() {

    }

    public JSONObject getJSONFromUrl(String url) {

        // Making HTTP request
        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(json);
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON String
        return jObj;

    }

注意:sdk 23不再支持DefaultHttpClient,因此建议将目标sdk 21与此代码一起使用。



2

其他答案还提到了Jackson和GSON-流行的Android附加JSON库,以及json.org,这是Android中包含的准系统JSON包。

但我认为也值得注意的是,Android现在拥有自己的全功能JSON API。

这是在Honeycomb:API级别11中添加的。

这包括
-android.util.JsonReader:docs
-android.util.JsonWriter:docs

我还将添加一个额外的考虑因素,使我回到Jackson和GSON:我发现使用第三方库而不是android。*包很有用,因为这样我编写的代码可以在客户端和服务器之间共享。这与JSON之类的东西特别相关,在JSON中,您可能希望将数据一端串行化为JSON以发送到另一端。对于类似的用例,如果在两端使用Java,则有助于避免引入android。*依赖项。

或者我猜一个人可以抓住相关的android。*源代码并将其添加到您的服务器项目中,但是我没有尝试过...



1

您只需要导入此

   import org.json.JSONObject;


  constructing the String that you want to send

 JSONObject param=new JSONObject();
 JSONObject post=new JSONObject();

我使用两个对象,因为您可以在另一个对象内使用jsonObject

post.put("username(here i write the key)","someusername"(here i put the value);
post.put("message","this is a sweet message");
post.put("image","http://localhost/someimage.jpg");
post.put("time":  "present time");

然后我将json放在另一个这样的文件中

  param.put("post",post);

这是我用来发出请求的方法

 makeRequest(param.toString());

public JSONObject makeRequest(String param)
{
    try
    {

设置连接

        urlConnection = new URL("your url");
        connection = (HttpURLConnection) urlConnection.openConnection();
        connection.setDoOutput(true);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-type", "application/json;charset=UTF-8");
        connection.setReadTimeout(60000);
        connection.setConnectTimeout(60000);
        connection.connect();

设置输出流

        dataOutputStream = new DataOutputStream(connection.getOutputStream());

我用它在logcat中查看我要发送的内容

        Log.d("OUTPUT STREAM  " ,param);
        dataOutputStream.writeBytes(param);
        dataOutputStream.flush();
        dataOutputStream.close();

        InputStream in = new BufferedInputStream(connection.getInputStream());
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        result = new StringBuilder();
        String line;

在这里字符串被构造

        while ((line = reader.readLine()) != null)
        {
            result.append(line);
        }

我使用此日志来查看响应中的内容

         Log.d("INPUTSTREAM: ",result.toString());

使用包含服务器响应的字符串实例化json

        jResponse=new JSONObject(result.toString());

    }
    catch (IOException e) {
        e.printStackTrace();
        return jResponse=null;
    } catch (JSONException e)
    {
        e.printStackTrace();
        return jResponse=null;
    }
    connection.disconnect();
    return jResponse;
}

谢谢您的时间。我使用您的代码将base64编码的字符串发送到django服务器,但是当我单击按钮以发送到服务器时,APP崩溃。您能帮我解决这个问题吗?
Noman marwat

0

如果您正在Android中寻找快速json解析功能,那么我建议您使用免费提供的工具。

JSON类创建器工具

它是免费使用的,并且在一两秒钟之内即可创建所有json解析类。。:D


0

尽管用户已经提供了很好的答案,例如鼓励使用GSON等。我还是建议使用org.json。它包含大多数GSON功能。它还允许您将json字符串作为参数传递给它的JSONObject,它将进行其他工作,例如:

JSONObject json = new JSONObject("some random json string");

此功能使其成为我个人的最爱。


0

有不同的开源库,可用于解析json。

org.json:-如果您想读取或写入json,则可以使用此库。首先创建JsonObject:-

JSONObject jsonObj = new JSONObject(<jsonStr>);

现在,使用此对象获取您的值:-

String id = jsonObj.getString("id");

您可以在此处看到完整的示例

Jackson databind:-如果您想将json绑定并解析到特定的POJO类,则可以使用jackson-databind库,这会将您的json绑定到POJO类:-

ObjectMapper mapper = new ObjectMapper();
post= mapper.readValue(json, Post.class);

您可以在此处看到完整的示例

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.