Wysyłanie i analizowanie obiektów JSON w systemie Android [zamknięte]


137

Chciałbym wysyłać wiadomości w postaci obiektów JSON na serwer i parsować odpowiedź JSON z serwera.

Przykład obiektu JSON

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

Próbuję przeanalizować JSON ręcznie, przechodząc atrybut po atrybucie. Czy jest jakaś biblioteka / narzędzie, których mogę użyć, aby ułatwić ten proces?


2
Ten adres URL nie jest już dostępny ... czy możesz go zaktualizować?
Cipi,

1
Oto szczegółowy przykład: Android - przykład analizy JSON
Paresh Mayani

1
@ Paresh Mayani & @ primpap .. Wiem, że możemy zapełnić dane z serwera za pomocą JSON otrzymanego z serwera metodą get, czuję się z tym dobrze .... ale jeśli używamy metody post do wysyłania danych na serwer, zrób ponownie wysyłamy dane jako JSON, odnoszę się do zapytania ofertowego primpap "Chciałbym wysłać wiadomości w postaci obiektów JSON do serwera Django" ..... Używam MySQL na serwerze .... lub Wysyłam obiekt JSON? ... czy możesz mi wyjaśnić te informacje ... lub jakiekolwiek linki, które pomogą mi zrozumieć koncepcję, będą pomocne, Dzięki
Devrath

Odpowiedzi:


118

Dziwię się, że nie wspomniano o tym: ale zamiast używać prostego procesu, a raczej ręcznego procesu z małym pakietem json.org, GSon i Jackson są znacznie wygodniejsi w użyciu. Więc:

Możesz więc faktycznie powiązać się z własnymi POJO, a nie z niektórymi pół-węzłami drzew lub listami i mapami. (a przynajmniej Jackson pozwala też na wiązanie się z takimi rzeczami (być może również GSON, nie jestem pewien), JsonNode, Map, List, jeśli naprawdę chcesz to zamiast „prawdziwych” obiektów)

EDYCJA 19-MAR-2014:

Kolejnym nowym kandydatem jest biblioteka Jackson jr : używa ona tego samego szybkiego parsera / generatora przesyłania strumieniowego co Jackson ( jackson-core), ale część związana z wiązaniem danych jest niewielka (50kB). Funkcjonalność jest bardziej ograniczona (brak adnotacji, tylko zwykłe Java Beans), ale wydajność powinna być szybka, a narzut inicjalizacji (pierwszego wywołania) również bardzo niski. Może to być dobry wybór, szczególnie w przypadku mniejszych aplikacji.


10
+1 dla GSON. W naszych aplikacjach na Androida korzystaliśmy w szczególności z obsługi strumieniowej obsługi strumieniowej GSON sites.google.com/site/gson/streaming .
Andre Steingress

FWIW, Jackson ma również streaming API: wiki.fasterxml.com/JacksonStreamingApi
StaxMan

2
Również +1 dla przesyłania strumieniowego GSON. Na początku zaimplementowano streaming Jacksona, ale chociaż działał w wersji do debugowania, ProGuard generował mnóstwo błędów, a wersja wydania powoduje awarie, które są trudne do wyśledzenia. Jestem pewien, że nie jest to problem związany z Jacksonem, ale spowodował, że przełączyłem się na GSON, który działał dobrze i wymagał tylko dodatkowych 14 KB do samego przesyłania strumieniowego.
sven

A dla głupich, nieprzewidywalnych ciągów i list json, np. ["Toto", "tata", ["monty", ["tor", "python"]]]? (rodzaj struktury danych wymagającej funkcji rekurencyjnych do jej wykorzystania)
christophe31

85

Możesz użyć org.json.JSONObject i org.json.JSONTokener . nie potrzebujesz żadnych zewnętrznych bibliotek, ponieważ te klasy są dostarczane z Android SDK


Ups! Tęsknie za tym. W rzeczywistości są to biblioteki org.json na stronie internetowej.
Gaurav Vaish

To jest to, czego używam i działa jak urok.
Adam

Byłoby wspaniale, gdyby można było podać przykład lub link do tego samego. W ten sposób łatwiej się nauczyć. :)
Primal Pappachan


1
Dużo więcej wygody, mniej kodu do napisania: jeden lub dwa wiersze zamiast dziesiątek.
StaxMan

31

GSON jest najłatwiejszy w użyciu i jest właściwą drogą, jeśli dane mają określoną strukturę.

Pobierz pliki gson .

Dodaj go do przywoływanych bibliotek.

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

Kod klasy Post

package com.tut.JSON;

public class Post {

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

4
Na ile jest to warte, kod można uprościć: konwersja JSONObject jest niepotrzebna. Settery i gettery są opcjonalne dla GSon; można dodać, jeśli ktoś chce, ale nie jest to absolutnie konieczne.
StaxMan

4
Tylko po to, by wyjaśnić komentarz StaxMan. Twój przykład polega na zrobieniu jString, przekonwertowaniu go na JSONObject, a następnie przekonwertowaniu go z powrotem na String do odczytania przez gson. Po prostu użyj pst = gson.fromJson (jString, Post.class). Wierzę, że to również wyeliminuje potrzebę próbowania. I jak wskazuje również StaxMan, settery i gettery w Post.class nie dodają żadnej wartości. Poprawienie twojego przykładu byłoby pomocne dla innych.
Matt


4

To jest klasa 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;

    }

Uwaga: DefaultHttpClient nie jest już obsługiwany przez sdk 23, dlatego zaleca się używanie docelowego zestawu SDk 21 z tym kodem.



2

Inne odpowiedzi zwróciły uwagę na Jackson i GSON - popularne dodatkowe biblioteki JSON dla Androida oraz json.org, pakiet JSON bare-bones, który jest zawarty w systemie Android.

Ale myślę, że warto również zauważyć, że Android ma teraz własne, w pełni funkcjonalne API JSON.

Zostało to dodane w Honeycomb: poziom API 11.

Obejmuje to
- android.util.JsonReader: docs i source
- android.util.JsonWriter: docs i source

Dodam również jedną dodatkową uwagę, która popycha mnie z powrotem w stronę Jacksona i GSON: Uważam, że przydatne jest używanie bibliotek innych firm, a nie pakietów Android. *, Ponieważ wtedy napisany kod może być współdzielony między klientem a serwerem. Jest to szczególnie istotne w przypadku czegoś takiego jak JSON, gdzie możesz chcieć serializować dane do JSON na jednym końcu, aby wysłać je na drugi koniec. W takich przypadkach, jeśli używasz Java na obu końcach, pomaga to uniknąć wprowadzania zależności android. *.

Albo chyba można pobrać odpowiedni kod źródłowy Androida. * I dodać go do projektu serwera, ale nie próbowałem tego ...



1

wystarczy to zaimportować

   import org.json.JSONObject;


  constructing the String that you want to send

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

używam dwóch obiektów, ponieważ możesz mieć obiekt jsonObject w innym

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

następnie umieściłem json post w innym w ten sposób

  param.put("post",post);

to jest metoda, której używam, aby złożyć wniosek

 makeRequest(param.toString());

public JSONObject makeRequest(String param)
{
    try
    {

ustawienie połączenia

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

ustawienie strumienia wyjściowego

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

Używam tego, aby zobaczyć w logcat, co wysyłam

        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;

tutaj struna jest konstruowana

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

używam tego dziennika, aby zobaczyć, co się dzieje w odpowiedzi

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

wystąpienie json za pomocą ciągu zawierającego odpowiedź serwera

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

z góry dziękuję za poświęcony czas. Używam twojego kodu do wysyłania zakodowanego ciągu base64 do serwera django, ale kiedy klikam przycisk, aby wysłać do serwera, aplikacja ulega awarii. Czy możesz mi pomóc, jak sobie z tym poradzić?
Noman marwat

0

jeśli szukasz szybkiego parsowania json w Androidzie, sugeruję narzędzie, które jest dostępne bezpłatnie.

Narzędzie do tworzenia klas JSON

Jest darmowy i tworzy całą klasę analizy json w ciągu jednej-dwóch sekund ..: D


0

Chociaż użytkownicy już teraz udzielają doskonałych odpowiedzi, takich jak zachęcanie do korzystania z GSON itp., Chciałbym zasugerować użycie org.json . Zawiera większość funkcjonalności GSON. Pozwala również na przekazanie ciągu json jako argumentu do jego JSONObject i zajmie się resztą, np .:

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

Ta funkcjonalność czyni go moim ulubionym.


0

Istnieją różne biblioteki open source, których można używać do analizowania plików json.

org.json: - Jeśli chcesz czytać lub pisać json, możesz użyć tej biblioteki. Najpierw utwórz JsonObject: -

JSONObject jsonObj = new JSONObject(<jsonStr>);

Teraz użyj tego obiektu, aby uzyskać wartości: -

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

Możesz zobaczyć pełny przykład tutaj

Jackson databind: - Jeśli chcesz powiązać i przeanalizować swój json z określoną klasą POJO, możesz użyć biblioteki jackson-databind, spowoduje to powiązanie twojego json z klasą POJO: -

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

Możesz zobaczyć pełny przykład tutaj

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.