Gửi và phân tích đối tượng JSON trong Android [đã đóng]


137

Tôi muốn gửi tin nhắn dưới dạng các đối tượng JSON đến một máy chủ và phân tích phản hồi JSON từ máy chủ.

Ví dụ về đối tượng JSON

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

Tôi đang cố phân tích JSON theo cách thủ công bằng cách đi thuộc tính theo thuộc tính. Có thư viện / tiện ích nào tôi có thể sử dụng để làm cho quá trình này dễ dàng hơn không?


2
URL đó không còn nữa ... bạn có thể cập nhật nó không?
Cipi

1
Dưới đây là một ví dụ chi tiết: Android - Ví dụ phân tích cú pháp JSON
Paresh Mayani

1
@ Paresh Mayani & @ primpap .. Tôi biết rằng chúng tôi có thể nhập dữ liệu từ máy chủ bằng cách nhận JSON từ máy chủ bằng phương thức get, tôi cảm thấy thoải mái với nó .... nhưng nếu chúng tôi sử dụng phương thức post để gửi dữ liệu đến máy chủ, hãy làm chúng tôi lại gửi dữ liệu dưới dạng JSON, tôi đang tham khảo Báo giá câu hỏi primpap "Tôi muốn gửi tin nhắn dưới dạng đối tượng JSON đến Máy chủ Django" ..... Tôi đang sử dụng Mysql trên máy chủ .... hoặc Tôi gửi đối tượng JSON? ... bạn có thể làm rõ thông tin này cho tôi .... hoặc bất kỳ liên kết nào giúp tôi hiểu khái niệm này sẽ hữu ích, Cảm ơn
Devrath

Câu trả lời:


118

Tôi ngạc nhiên khi những điều này chưa được đề cập: nhưng thay vì sử dụng quy trình thủ công thay vì thủ công với gói nhỏ của json.org, GSon và Jackson thuận tiện hơn nhiều khi sử dụng. Vì thế:

Vì vậy, bạn thực sự có thể liên kết với POJO của riêng bạn, chứ không phải một số nút cây nửa khẳng định hoặc Danh sách và Bản đồ. (và ít nhất Jackson cũng cho phép ràng buộc với những thứ như vậy (có lẽ cả GSON, không chắc chắn), JsonNode, Bản đồ, Danh sách, nếu bạn thực sự muốn những thứ này thay vì các đối tượng 'thực')

EDIT 19 tháng 3 năm 2014:

Một ứng cử viên mới khác là thư viện Jackson jr : nó sử dụng trình phân tích / trình phân tích phát trực tuyến nhanh tương tự như Jackson ( jackson-core), nhưng phần ràng buộc dữ liệu rất nhỏ (50kB). Chức năng bị hạn chế hơn (không có chú thích, chỉ là Đậu Java thông thường), nhưng hiệu năng phải nhanh và tốc độ khởi tạo (cuộc gọi đầu tiên) cũng rất thấp. Vì vậy, nó chỉ có thể là sự lựa chọn tốt, đặc biệt là cho các ứng dụng nhỏ hơn.


10
+1 cho GSON. Chúng tôi đặc biệt đã sử dụng các trang web hỗ trợ phát trực tuyến của GSON.google.com/site/gson/streaming trong các ứng dụng Android của chúng tôi.
Andre Steingress

FWIW, Jackson cũng có API phát trực tuyến: wiki.fasterxml.com/JacksonStreamingApi
StaxMan

2
Cũng +1 cho phát trực tuyến GSON. Đã triển khai phát trực tuyến Jackson lúc đầu nhưng mặc dù có chức năng trong phiên bản gỡ lỗi, ProGuard đã tạo ra vô số lỗi và phiên bản phát hành gây ra sự cố khó theo dõi. Tôi chắc chắn đây không phải là vấn đề liên quan đến Jackson, nhưng nó đã khiến tôi chuyển sang GSON hoạt động tốt và chỉ cần thêm 14kB cho việc phát trực tuyến.
sven

Và đối với chuỗi trộn json ngu ngốc không dự đoán được và liệt kê ex: ["toto", "tata", ["monty", ["tor", "python"]]]? (loại cấu trúc dữ liệu yêu cầu các hàm đệ quy để tiêu thụ nó)
christophe31

85

Bạn có thể sử dụng org.json.JSONObjectorg.json.JSONTokener . bạn không cần bất kỳ thư viện bên ngoài nào vì các lớp này đi kèm với Android SDK


Giáo sư! Tôi đã bỏ lỡ nó. Nguyên vẹn, chúng là các thư viện org.json trên trang web.
Gaurav Vaish

Đây là những gì tôi sử dụng, và nó hoạt động như một bùa mê.
Adam

Sẽ thật tuyệt nếu một ví dụ hoặc một liên kết đến cùng có thể được đưa ra. Nó dễ dàng hơn để học theo cách đó. :)
Pappachan nguyên thủy


1
Tiện lợi hơn nhiều, ít mã để viết: một hoặc hai dòng thay vì hàng chục.
StaxMan

31

GSON là dễ sử dụng nhất và cách để đi nếu dữ liệu có cấu trúc xác định.

Tải gson .

Thêm nó vào các thư viện được tham chiếu.

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

Mã cho lớp Post

package com.tut.JSON;

public class Post {

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

4
Đối với giá trị của nó, mã có thể được đơn giản hóa: chuyển đổi JSONObject là không cần thiết. Và setters và getters là tùy chọn cho GSon; có thể được thêm vào nếu muốn, nhưng không thực sự cần thiết.
StaxMan

4
Chỉ cần làm rõ nhận xét của StaxMan. Ví dụ của bạn đang lấy jString, chuyển đổi nó thành JSONObject, sau đó chuyển đổi nó trở lại thành Chuỗi để gson đọc. Đơn giản chỉ cần sử dụng pst = gson.fromJson (jString, Post. Class). Tôi tin rằng điều này cũng sẽ thoát khỏi nhu cầu thử bắt. Và như StaxMan cũng chỉ ra, các setters & getters trong Post. Class không có giá trị. Nó sẽ hữu ích cho những người khác để sửa ví dụ của bạn.
Matt

Tôi đã xóa phần chuyển đổi kép khỏi câu trả lời
whlk

4

Đây là lớp 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;

    }

Lưu ý: DefaultHttpClient không còn được hỗ trợ bởi sdk 23, vì vậy nên sử dụng sdk 21 đích với mã này.


3

JSON thực sự không có gì. Dấu ngoặc nhọn dành cho "đối tượng" (mảng kết hợp) và dấu ngoặc vuông dành cho mảng không có khóa (được lập chỉ mục bằng số). Theo như làm việc với nó trong Android, có các lớp đã sẵn sàng cho bao gồm trong sdk (không yêu cầu tải xuống).

Kiểm tra các lớp này: http://developer.android.com/reference/org/json/package-summary.html


Tôi cho rằng bạn có nghĩa là niềng răng xoăn và không góc ngoặc!
Gaurav Vaish

2

Các câu trả lời khác đã ghi nhận Jackson và GSON - các thư viện JSON bổ trợ phổ biến cho Android và json.org, gói JSON đơn giản được bao gồm trong Android.

Nhưng tôi nghĩ cũng đáng chú ý rằng Android hiện có API JSON đầy đủ tính năng của riêng mình.

Điều này đã được thêm vào trong Honeycomb: API cấp 11.

Điều này bao gồm
- android.util.JsonReader: docsnguồn
- android.util.JsonWriter: docssource

Tôi cũng sẽ thêm một sự xem xét bổ sung đẩy tôi trở lại với Jackson và GSON: Tôi thấy việc sử dụng các thư viện của bên thứ 3 thay vì các gói android. * Vì sau đó mã tôi viết có thể được chia sẻ giữa máy khách và máy chủ. Điều này đặc biệt có liên quan đến một cái gì đó như JSON, nơi bạn có thể muốn tuần tự hóa dữ liệu sang JSON ở một đầu để gửi đến đầu kia. Đối với các trường hợp sử dụng như vậy, nếu bạn sử dụng Java ở cả hai đầu, điều đó giúp tránh giới thiệu phụ thuộc android. *.

Hoặc tôi đoán người ta có thể lấy mã nguồn Android. * Có liên quan và thêm nó vào dự án máy chủ của bạn, nhưng tôi đã không thử ...


1

Bạn có thể tải xuống một thư viện từ http://json.org (Json-lib hoặc org.json) và sử dụng nó để phân tích / tạo JSON


1

bạn chỉ cần nhập cái này

   import org.json.JSONObject;


  constructing the String that you want to send

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

tôi đang sử dụng hai đối tượng vì bạn có thể có một jsonObject trong một đối tượng khác

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

sau đó tôi đặt bài đăng json bên trong khác

  param.put("post",post);

đây là phương pháp mà tôi sử dụng để đưa ra yêu cầu

 makeRequest(param.toString());

public JSONObject makeRequest(String param)
{
    try
    {

thiết lập kết nối

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

thiết lập đầu ra

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

tôi sử dụng điều này để xem trong logcat những gì tôi đang gửi

        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;

ở đây chuỗi được xây dựng

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

tôi sử dụng nhật ký này để xem những gì nó đến trong phản hồi

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

kích hoạt một json với Chuỗi chứa phản hồi của máy chủ

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

cảm ơn bạn đã dành thời gian trước Tôi sử dụng mã của bạn để gửi chuỗi mã hóa base64 đến máy chủ django nhưng khi tôi nhấp vào nút để gửi đến máy chủ thì APP gặp sự cố. Bạn có thể giúp tôi làm thế nào để giải quyết điều này?
Noman marwat

0

Nếu bạn đang tìm kiếm phân tích json nhanh trong Android hơn tôi đề nghị bạn một công cụ có sẵn miễn phí.

Công cụ tạo lớp JSON

Nó miễn phí để sử dụng và nó tạo ra tất cả các lớp phân tích json của bạn trong vòng một hai giây ..: D


0

Mặc dù đã có những câu trả lời xuất sắc được cung cấp bởi người dùng như khuyến khích sử dụng GSON, v.v. Tôi muốn đề xuất sử dụng org.json . Nó bao gồm hầu hết các chức năng của GSON. Nó cũng cho phép bạn truyền chuỗi json làm đối số cho JSONObject và nó sẽ chăm sóc phần còn lại, ví dụ:

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

Chức năng này làm cho nó yêu thích cá nhân của tôi.


0

Có các thư viện mã nguồn mở khác nhau, mà bạn có thể sử dụng để phân tích cú pháp json.

org.json: - Nếu bạn muốn đọc hoặc viết json thì bạn có thể sử dụng thư viện này. Đầu tiên tạo JsonObject: -

JSONObject jsonObj = new JSONObject(<jsonStr>);

Bây giờ, sử dụng đối tượng này để nhận các giá trị của bạn: -

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

Bạn có thể xem ví dụ đầy đủ ở đây

Jackson databind: - Nếu bạn muốn liên kết và phân tích json của bạn với lớp POJO cụ thể, thì bạn có thể sử dụng thư viện jackson-databind, điều này sẽ liên kết json của bạn với lớp POJO: -

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

Bạn có thể xem ví dụ đầy đủ ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.