Надсилання та розбір об’єктів JSON в 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 Parsing приклад
Paresh Mayani

1
@ Paresh Mayani & @ primpap .. Я знаю, що ми можемо заповнювати дані з сервера за допомогою JSON, отриманого від сервера за допомогою методу get, мені це зручно .... але якщо ми використовуємо метод post для надсилання даних на сервер, зробіть ми знову надсилаємо дані у вигляді JSON, я звертаюсь до цитування запитання primpap "Я хотів би надсилати повідомлення у вигляді об'єктів JSON на сервер Django" ..... я використовую Mysql на сервері .... або Я надсилаю об'єкт JSON? ... ви можете мені уточнити цю інформацію .... або будь-які посилання, які допомагають мені зрозуміти концепцію, будуть корисні, Дякую
Devrath

Відповіді:


118

Я здивований, що про них не згадували: але замість того, щоб використовувати голі кістки, а не ручний процес з маленьким пакетом json.org, GSon та Джексон набагато зручніше використовувати. Так:

Таким чином, ви можете фактично прив’язуватися до власних POJO, а не до деяких напівзв’язаних вузлів дерев або списків та карт. (і принаймні Джексон дозволяє також прив’язувати до таких речей (можливо, також GSON, не впевнений), JsonNode, Map, List, якщо ви дійсно хочете їх замість "реальних" об'єктів)

EDIT 19-MAR-2014:

Ще одним новим претендентом є бібліотека Jackson jr : вона використовує такий же швидкий потоковий аналізатор / генератор, що і Jackson ( jackson-core), але частина прив'язки даних є мініатюрною (50 кБ). Функціональність обмежена (відсутність анотацій, просто звичайні Java Beans), але продуктивність повинна бути швидкою, а ініціалізація (перший дзвінок) також дуже низька. Тож це може бути хорошим вибором, особливо для менших додатків.


10
+1 для GSON. Ми особливо використовували потокову підтримку GSON в sites.google.com/site/gson/streaming в нашому Android додатків.
Andre Steingress

FWIW, Джексон також має API для потокового зв’язку: wiki.fasterxml.com/JacksonStreamingApi
StaxMan

2
Також +1 для потокової передачі GSON. Спочатку реалізована потокова програма Джексона, але хоч і функціональна у налагоджувальній версії, ProGuard генерував безліч помилок, а версія версії викликає збої, які важко відстежити. Я впевнений, що це не проблема Джексона, але це змусило мене перейти на GSON, який спрацював нормально і вимагав лише додаткових 14 КБ для просто трансляції.
sven

А для дурного непередбачуваного змішування рядка json та списків ex: ["toto", "tata", ["monty", ["tor", "python"]]]? (вид структури даних, що вимагає рекурсивних функцій для споживання)
christophe31

85

Ви можете використовувати org.json.JSONObject та org.json.JSONTokener . вам не потрібні зовнішні бібліотеки, оскільки ці класи поставляються з Android SDK


На жаль! Я пропустив це. Інфакт - це бібліотеки org.json на веб-сайті.
Гаурав Вайш

Це те, що я використовую, і це працює як шарм.
Адам

Було б чудово, якби можна було навести приклад або посилання на те саме. Так легше навчитися. :)
Первинний Паппачан


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

Код для класу Post

package com.tut.JSON;

public class Post {

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

4
Для чого це варто, можна спростити код: що перетворення JSONObject не є необхідним. А сетери та геттери необов’язкові для GSon; можна додати, якщо хочеться, але це не суворо необхідно.
StaxMan

4
Просто для уточнення коментаря StaxMan. Ваш приклад - це взяти jString, перетворити його в JSONObject, потім перетворити його назад у String, щоб gson читав. Просто використовуйте pst = gson.fromJson (jString, Post.class). Я вірю, що це також позбудеться потреби у спробі лову. І як також вказує StaxMan, сетери та геттери в Post.class не додають значення. Іншим було б корисно виправити ваш приклад.
Метт

Я вилучив подвійну частину конверсії з відповіді
моркнув

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


Я думаю, ви мали на увазі фігурні дужки, а не кутові дужки!
Гаурав Вайш

2

Інші відповіді відзначили Джексона та GSON - популярні додаткові бібліотеки JSON для Android, і json.org - пакет JSON з голими кістками, що входить до Android.

Але я думаю, що також варто відзначити, що в Android зараз є власний повнофункціональний JSON API.

Це було додано в Honeycomb: API рівня 11.

Сюди входять
: android.util.JsonReader: docs та джерело
- android.util.JsonWriter: docs та джерело

Я також додам ще одне додаткове враження, яке відштовхує мене назад до Джексона та GSON: я вважаю корисним використовувати сторонні бібліотеки, а не пакети для android. *, Оскільки тоді код, який я пишу, можна поділити між клієнтом та сервером. Це особливо актуально для чогось на зразок JSON, де ви, можливо, захочете серіалізувати дані до JSON з одного кінця для надсилання на інший кінець. Для таких випадків використання, якщо ви використовуєте Java на обох кінцях, це допомагає уникнути введення залежностей від 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());

Я використовую це, щоб побачити в логкатах, що я надсилаю

        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

якщо ви шукаєте швидкий розбір json в android, ніж я пропоную вам інструмент, який є у вільному доступі.

Інструмент творця JSON Class Creator

Він безкоштовний у використанні, і це створить ваш клас розбору всіх 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);

Повний приклад ви можете подивитися тут

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.