การส่งและการแยกวิเคราะห์ JSON Objects ใน Android [ปิด]


137

ฉันต้องการส่งข้อความในรูปแบบของวัตถุ JSON ไปยังเซิร์ฟเวอร์และแยกการตอบสนอง JSON จากเซิร์ฟเวอร์

ตัวอย่างของวัตถุ JSON

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

ฉันพยายามแยก JSON ด้วยตนเองโดยไปที่แอตทริบิวต์โดยแอตทริบิวต์ มีห้องสมุด / ยูทิลิตี้ที่ฉันสามารถใช้เพื่อทำให้กระบวนการนี้ง่ายขึ้นหรือไม่


2
URL นั้นไม่สามารถใช้งานได้อีกต่อไป ... คุณสามารถอัปเดตได้หรือไม่
Cipi

1
นี่คือตัวอย่างโดยละเอียด: Android - ตัวอย่างการแยกวิเคราะห์ JSON
Paresh Mayani

1
@ Paresh Mayani & @ primpap .. ฉันรู้ว่าเราสามารถเติมข้อมูลจากเซิร์ฟเวอร์โดยใช้ JSON ที่ได้รับจากเซิร์ฟเวอร์โดยใช้วิธีการรับฉันไม่พอใจกับมัน .... แต่ถ้าเราใช้วิธีการโพสต์เพื่อส่งข้อมูลไปยังเซิร์ฟเวอร์ให้ทำ เราส่งข้อมูลเป็น JSON อีกครั้งฉันหมายถึงใบเสนอราคาของคำถาม primpap "ฉันต้องการส่งข้อความในรูปแบบของวัตถุ JSON ไปยังเซิร์ฟเวอร์ Django" ..... ฉันใช้ Mysql บนเซิร์ฟเวอร์ .... หรือ ฉันส่งวัตถุ JSON หรือไม่ ... คุณช่วยอธิบายข้อมูลนี้ให้ฉันได้ .... หรือลิงก์ใด ๆ ที่ช่วยฉันเข้าใจว่าแนวคิดนี้จะมีประโยชน์ขอบคุณ
Devrath

คำตอบ:


118

ฉันประหลาดใจที่สิ่งเหล่านี้ไม่ได้ถูกกล่าวถึง: แต่แทนที่จะใช้กระดูกเปลือยเปล่าแทนที่จะทำด้วยมือกับแพ็คเกจเล็ก ๆ ของ json.org, GSon และ Jackson สะดวกกว่าการใช้มาก ดังนั้น:

ดังนั้นคุณสามารถผูกกับ POJO ของคุณได้จริง ๆ ไม่ใช่โหนดต้นไม้หรือครึ่งหนึ่งของรายการและแผนที่ (และอย่างน้อยแจ็คสันก็อนุญาตให้ทำสิ่งต่าง ๆ เช่นกัน (อาจเป็น GSON เช่นกันไม่แน่ใจ), JsonNode, แผนที่, รายการถ้าคุณต้องการสิ่งเหล่านี้แทนวัตถุ 'ของจริง')

แก้ไข 19 มีนาคม 2014:

คู่แข่งรายใหม่อีกรายคือห้องสมุดJackson jr : ใช้ตัวแยกวิเคราะห์ / สตรีมมิ่ง Streaming แบบเร็วเช่นเดียวกับ Jackson ( jackson-core) แต่ส่วนที่มีผลผูกพันกับข้อมูลมีขนาดเล็ก (50kB) ฟังก์ชั่นมี จำกัด มากขึ้น (ไม่มีคำอธิบายประกอบเพียงแค่ Java Beans ปกติ) แต่ประสิทธิภาพที่ควรจะรวดเร็วและการเริ่มต้น (สายแรก) ค่าใช้จ่ายต่ำมากเช่นกัน ดังนั้นมันอาจเป็นทางเลือกที่ดีโดยเฉพาะอย่างยิ่งสำหรับแอปขนาดเล็ก


10
+1 สำหรับ GSON เราได้ใช้โดยเฉพาะอย่างยิ่งการสนับสนุนสตรีมมิ่ง GSON ของ sites.google.com/site/gson/streamingในปพลิเคชัน Android ของเรา
Andre Steingress

FWIW, Jackson ยังมีสตรีมมิ่ง API: wiki.fasterxml.com/JacksonStreamingApi
StaxMan

2
+1 สำหรับการสตรีม GSON ด้วย การใช้งาน Jackson สตรีมมิ่งในตอนแรก แต่แม้ว่าจะใช้งานได้ในเวอร์ชันดีบั๊ก ProGuard ก็สร้างข้อผิดพลาดจำนวนมากและรุ่นที่วางจำหน่ายทำให้เกิดปัญหาซึ่งยากต่อการติดตาม ฉันแน่ใจว่านี่ไม่ใช่ปัญหาที่เกี่ยวข้องกับแจ็คสัน แต่มันทำให้ฉันเปลี่ยนไปใช้ GSON ซึ่งทำงานได้ดีและต้องการเพียง 14kB เพิ่มเติมสำหรับการสตรีมเท่านั้น
sven

และสำหรับสตริงการผสม json ที่ไม่สามารถคาดเดาได้โง่และรายการ ex: ["toto", "tata", ["monty", ["tor", "python"]]]] (ชนิดของโครงสร้างข้อมูลที่ต้องการฟังก์ชั่นแบบเรียกซ้ำเพื่อใช้งาน)
christophe31

85

คุณสามารถใช้org.json.JSONObjectและorg.json.JSONTokener คุณไม่ต้องการห้องสมุดภายนอกเนื่องจากคลาสเหล่านี้มาพร้อมกับ Android SDK


อ๊ะ! ฉันคิดถึงสิ่งนั้น Infact เป็นไลบรารี org.json บนเว็บไซต์
Gaurav Vaish

นี่คือสิ่งที่ฉันใช้และใช้งานได้เหมือนมีเสน่ห์
อดัม

มันจะดีมากถ้ามีตัวอย่างหรือลิงค์ไปยังลิงก์เดียวกัน เรียนรู้วิธีนั้นง่ายกว่า :)
Primal Pappachan


1
ความสะดวกสบายมากขึ้นมากน้อยเขียนโค้ด: หนึ่งหรือสองบรรทัดแทนที่จะเป็นหลายสิบ
StaxMan

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 นั้นไม่จำเป็น และ setters และ getters เป็นทางเลือกสำหรับ GSon; สามารถเพิ่มได้หากต้องการ แต่ไม่จำเป็นอย่างเคร่งครัด
StaxMan

4
เพียงเพื่อชี้แจงความคิดเห็นของ StaxMan ตัวอย่างของคุณคือการนำ jString แปลงไปเป็น JSONObject แล้วแปลงกลับเป็นสตริงเพื่อให้ gson อ่าน เพียงใช้ pst = gson.fromJson (jString, Post.class) ฉันเชื่อว่าสิ่งนี้จะกำจัดความจำเป็นในการลองจับ และในฐานะที่เป็น StaxMan ยังชี้ให้เห็น setters & getters ใน Post.class ไม่เพิ่มมูลค่าใด ๆ ผู้อื่นจะเป็นประโยชน์ในการแก้ไขตัวอย่างของคุณ
Matt

ฉันลบส่วนการแปลงสองครั้งออกจากคำตอบ
whlk

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;

    }

หมายเหตุ: DefaultHttpClient ไม่รองรับ sdk 23 อีกต่อไปดังนั้นจึงแนะนำให้ใช้ sdk 21 เป้าหมายด้วยรหัสนี้


3

JSON ไม่มีอะไรจริงๆ วงเล็บปีกกาใช้สำหรับ "วัตถุ" (อาเรย์เชื่อมโยง) และวงเล็บเหลี่ยมใช้สำหรับอาร์เรย์ที่ไม่มีคีย์ (ทำดัชนีตัวเลข) เท่าที่ทำงานกับมันใน Android มีชั้นเรียนพร้อมสำหรับที่รวมอยู่ใน sdk (ไม่จำเป็นต้องดาวน์โหลด)

ตรวจสอบคลาสเหล่านี้: http://developer.android.com/reference/org/json/package-summary.html


ฉันคิดว่าคุณหมายถึงเหล็กดัดไม่ใช่ไม่ใช่เหล็กเหลี่ยมเลย!
Gaurav Vaish

2

คำตอบอื่น ๆ ได้ระบุ Jackson และ GSON - ไลบรารี JSON ยอดนิยมสำหรับ Android และ json.org ซึ่งเป็นแพคเกจ JSON แบบไม่มีกระดูกที่รวมอยู่ใน Android

แต่ฉันคิดว่ามันก็เป็นที่น่าสังเกตว่าตอนนี้ Android มี JSON API แบบเต็มของตัวเองแล้ว

สิ่งนี้ถูกเพิ่มใน Honeycomb: API ระดับ 11

สิ่งนี้ประกอบด้วย
- android.util.JsonReader: เอกสารและแหล่งที่มา
- android.util.JsonWriter: เอกสารและแหล่งที่มา

ฉันจะเพิ่มการพิจารณาเพิ่มเติมอีกหนึ่งข้อที่ผลักดันฉันกลับไปที่แจ็คสันและ GSON: ฉันพบว่ามีประโยชน์ในการใช้ห้องสมุดบุคคลที่สามมากกว่า Android * แพคเกจเพราะจากนั้นโค้ดที่ฉันเขียนสามารถใช้ร่วมกันระหว่างไคลเอนต์และเซิร์ฟเวอร์ สิ่งนี้มีความเกี่ยวข้องเป็นพิเศษกับสิ่งต่างๆเช่น 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 ด้วย String ที่มีการตอบกลับของเซิร์ฟเวอร์

        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 แต่เมื่อฉันคลิกปุ่มเพื่อส่งไปยังเซิร์ฟเวอร์แอพจะขัดข้อง คุณช่วยฉันจัดการเรื่องนี้ได้อย่างไร
Noman marwat

0

หากคุณกำลังมองหา json อย่างรวดเร็วในการแยกวิเคราะห์ใน Android กว่าฉันขอแนะนำเครื่องมือที่สามารถใช้ได้อย่างอิสระ

เครื่องมือ JSON Class Creator

ใช้งานได้ฟรีและสร้างคลาสการแยกวิเคราะห์ json ทั้งหมดของคุณภายในหนึ่งวินาที


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

คุณสามารถดูตัวอย่างสมบูรณ์ได้ที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.