Jak parsować JSON w Javie

1048

Mam następujący tekst JSON. W jaki sposób można analizować je, aby uzyskać wartości pageName, pagePic, post_id, itd.?

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    },
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": "1234567890",
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": "2",
              "comments": [],
              "timeOfPost": "1234567890"
         }
    ]
}
Muhammad Maqsoodur Rehman
źródło
7
Biblioteki JSON wbudowane w java to najszybszy sposób, ale z mojego doświadczenia wynika, że ​​GSON jest najlepszą biblioteką do bezproblemowego parsowania JSON w POJO.
Iman Akbari
16
To pierwsze wysoko głosowane i chronione pytanie, na które odpowiedzi najbardziej
pomyliłem
6
@JaysonMinard zgodził się. Zapytany o interwencję mod. To powinno być naprawdę zamknięte. Początkowo założyłem (niesłusznie), że nie mogę tego zrobić, gdy pytanie jest chronione, więc nie chroniłem go i zrobiłem swoje. Ponownie go zabezpieczyłem, aby zapobiec odpowiedziom o niskiej liczbie powtórzeń i tym podobnych, czekając na modyfikację.
Mena
4
„To pytanie nie pokazuje żadnego wysiłku badawczego” - etykietka przycisku Downvote
Jean-François Corbett
6
To pytanie jest omawiane na Meta .
Mark Amery

Odpowiedzi:

753

Org.json biblioteka jest łatwy w użyciu. Przykładowy kod poniżej:

import org.json.*;

String jsonString = ... ; //assign your JSON String here
JSONObject obj = new JSONObject(jsonString);
String pageName = obj.getJSONObject("pageInfo").getString("pageName");

JSONArray arr = obj.getJSONArray("posts");
for (int i = 0; i < arr.length(); i++)
{
    String post_id = arr.getJSONObject(i).getString("post_id");
    ......
}

Możesz znaleźć więcej przykładów z: Parsuj JSON w Javie

Słoik do pobrania: http://mvnrepository.com/artifact/org.json/json

użytkownik1931858
źródło
15
Zgadzam się z @StaxMan. Właśnie próbowałem org.json i jest to okropnie kłopotliwe. Na przykład tak naprawdę nie działa ze standardowymi typami kolekcji Java.
Ken Williams,
7
@StaxMan Wybrałbym org.jsoninne biblioteki do prostego parsowania JSON, nawet nie patrząc. Jest to biblioteka referencyjna, którą stworzył Douglas Crockford (odkrywca JSON).
Omar Al-Ithawi
31
@OmarIthawi to po prostu głupie. To dowód koncepcji z niewygodnym API, nieefektywną implementacją. Wydaje mi się, że lepiej jest rozważać biblioteki według ich własnych zalet, niż próbować wywnioskować jakość z widoczności jej autorów - Doug osiągnął wiele rzeczy, ale tak naprawdę nie zmienia to cech konkretnej biblioteki. 10 lat temu była to jedyna gra w mieście, ale od tego czasu odnotowano wiele pozytywnych postępów. To jest jak Struts of json libs.
StaxMan,
12
org.json jest jedną z najgorszych bibliotek json. Przed dokonaniem wyboru należy sprawdzić zestaw funkcji i wydajność dostępnych bibliotek json. Oto test porównawczy, w którym porównałem Jacksona, Gsona, org.jsona, Gensona przy użyciu JMH: github.com/fabienrenaud/java-json-benchmark . jackson jest tutaj wyraźnym zwycięzcą.
fabien
4
Licencja nie obejmuje żadnych powszechnie używanych licencji Open Source, a także posiada prawa autorskie.
Christian Vielma,
536

Dla przykładu załóżmy, że masz klasę Personz tylko name.

private class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Google GSON ( Maven )

Mój osobisty faworyt co do wielkiej serializacji / deserializacji obiektów JSON.

Gson g = new Gson();

Person person = g.fromJson("{\"name\": \"John\"}", Person.class);
System.out.println(person.name); //John

System.out.println(g.toJson(person)); // {"name":"John"}

Aktualizacja

Jeśli chcesz uzyskać pojedynczy atrybut, możesz to łatwo zrobić również z biblioteką Google:

JsonObject jsonObject = new JsonParser().parse("{\"name\": \"John\"}").getAsJsonObject();

System.out.println(jsonObject.get("name").getAsString()); //John

Org.JSON ( Maven )

Jeśli nie potrzebujesz deseryzacji obiektów, ale po prostu uzyskać atrybut, możesz wypróbować org.json ( lub spójrz na przykład GSON powyżej! )

JSONObject obj = new JSONObject("{\"name\": \"John\"}");

System.out.println(obj.getString("name")); //John

Jackson ( Maven )

ObjectMapper mapper = new ObjectMapper();
Person user = mapper.readValue("{\"name\": \"John\"}", Person.class);

System.out.println(user.name); //John
SDekov
źródło
16
Dobra odpowiedź. Jedna sugestia drobnych ulepszeń: zarówno GSON, jak i Jackson obsługują również użycie reprezentacji drzewa JSON (dla Jacksona są to JsonNodes, GSON ma coś podobnego). Może warto wyświetlać fragmenty, ponieważ jest to jedyny sposób, w jaki oferuje org.json.
StaxMan,
Dwie inne biblioteki, o których warto wspomnieć (w celu zapewnienia kompletności): json-simple i Oracle's JSONP
jake stayman
3
@NeonWarge, dlaczego? Wydaje mi się, że ta odpowiedź zakłada, że ​​już zdefiniowano klasę Java, która zawiera dokładnie te same pola co łańcuch JSON, nic więcej i nic więcej. To dość mocne założenie.
Andrea Lazzarotto,
1
json-simple i oracle's jsonp działają strasznie: github.com/fabienrenaud/java-json-benchmark Dla wydajności wybierz jackson lub dsljson.
fabien
GSON nie obsługuje dynamicznego filtrowania pól na poziomach innych niż root!
Gangnus,
102
  1. Jeśli chcesz utworzyć obiekt Java z JSON i odwrotnie, użyj słoików GSON lub JACKSON innych firm itp.

    //from object to JSON 
    Gson gson = new Gson();
    gson.toJson(yourObject);
    
    // from JSON to object 
    yourObject o = gson.fromJson(JSONString,yourObject.class);
  2. Ale jeśli chcesz po prostu przeanalizować ciąg JSON i uzyskać pewne wartości (LUB utworzyć ciąg JSON od zera, aby wysłać go przez drut), po prostu użyj jar JaveEE, który zawiera JsonReader, JsonArray, JsonObject itp. Możesz pobrać implementację tego spec jak javax.json. Dzięki tym dwóm słojom jestem w stanie przeanalizować json i użyć wartości.

    Te interfejsy API są zgodne z modelem analizującym DOM / SAX XML.

    Response response = request.get(); // REST call 
        JsonReader jsonReader = Json.createReader(new StringReader(response.readEntity(String.class)));
        JsonArray jsonArray = jsonReader.readArray();
        ListIterator l = jsonArray.listIterator();
        while ( l.hasNext() ) {
              JsonObject j = (JsonObject)l.next();
              JsonObject ciAttr = j.getJsonObject("ciAttributes");
nieokreślony
źródło
4
@nondescript Gdybym musiał zgadywać, powiedziałbym, że został odrzucony, ponieważ nie odpowiada na pytanie pierwotnego plakatu: „Jaki jest wymagany kod?” Odpowiedzi, które zostały poddane ocenie, zawierały fragmenty kodu.
jewbix.cube
4
Uwaga: Jackson i GSON obsługują wiązanie w stylu drzewa i / lub wiązanie Maps / Lists, więc nie ma potrzeby używania pakietu Java EE (javax.json). javax.json ma niewiele do zaoferowania poza Jacksonem lub GSON.
StaxMan
Sugeruję dodanie łącza do biblioteki JavaEE.
Basil Bourque,
72

Parser Quick-Json jest bardzo prosty, elastyczny, bardzo szybki i konfigurowalny. Spróbuj

Funkcje:

  • Zgodny ze specyfikacją JSON (RFC4627)
  • Analizator składni JSON o wysokiej wydajności
  • Obsługuje elastyczne / konfigurowalne podejście analizujące
  • Konfigurowalne sprawdzanie poprawności par klucz / wartość dowolnej hierarchii JSON
  • Łatwy w użyciu # Bardzo mały ślad
  • Podnosi przyjazne dla programistów i łatwe do śledzenia wyjątki
  • Wtykowa obsługa niestandardowej walidacji - klucze / wartości mogą być sprawdzane przez konfigurację niestandardowych walidatorów, gdy zostaną napotkane
  • Obsługa sprawdzania poprawności i niezweryfikowania analizatora składni
  • Obsługa dwóch typów konfiguracji (JSON / XML) do korzystania z szybkiego analizatora składni JSON
  • Wymaga JDK 1.5
  • Brak zależności od bibliotek zewnętrznych
  • Obsługa generowania JSON poprzez serializację obiektów
  • Obsługa wyboru typu kolekcji podczas parsowania

Można go użyć w następujący sposób:

JsonParserFactory factory=JsonParserFactory.getInstance();
JSONParser parser=factory.newJsonParser();
Map jsonMap=parser.parseJson(jsonString);
rputta
źródło
3
Czy jest dostępny javadoc?
jboi
24
Ten pakiet nie obsługuje pustych wartości podczas analizowania. Na przykład: ... „opis”: „”… zgłasza wyjątek
Iwan
6
Naprawiłem ten problem (i wiele innych) w code.google.com/p/quick-json/issues/detail?id=11 Mam nadzieję, że autor poświęci trochę czasu, aby naprawić go w oficjalnej wersji.
noamik
8
Z wymienionych funkcji nic nie jest wyjątkowe w porównaniu z innymi opcjami - a twierdzenie o wysokiej wydajności nie jest w żaden sposób obsługiwane; w przeciwieństwie do bardziej dojrzałych bibliotek (Gson, Jackson, Genson, Boon), które są uwzględnione w testach porównawczych, takich jak github.com/eishay/jvm-serializers , github.com/novoj/JavaJsonPerformanceTest lub developer.com/lang/jscript/… - I nie widziałem tej biblioteki włączonej do testów ani nie wspomina o jej szerokim zastosowaniu.
StaxMan
26
Projekt wydaje się być martwy i wydaje się, że nie jest już hostowany w centralnym repozytorium Maven.
8bitjunkie
40

Możesz użyć Google Gson .

Korzystając z tej biblioteki, wystarczy stworzyć model o tej samej strukturze JSON. Następnie model jest automatycznie wypełniany. Musisz wywoływać zmienne jako klucze JSON lub użyć, @SerializedNamejeśli chcesz użyć innych nazw.

JSON

Z twojego przykładu:

{
    "pageInfo": {
        "pageName": "abc",
        "pagePic": "http://example.com/content.jpg"
    }
    "posts": [
        {
            "post_id": "123456789012_123456789012",
            "actor_id": "1234567890",
            "picOfPersonWhoPosted": "http://example.com/photo.jpg",
            "nameOfPersonWhoPosted": "Jane Doe",
            "message": "Sounds cool. Can't wait to see it!",
            "likesCount": "2",
            "comments": [],
            "timeOfPost": "1234567890"
        }
    ]
}

Model

class MyModel {

    private PageInfo pageInfo;
    private ArrayList<Post> posts = new ArrayList<>();
}

class PageInfo {

    private String pageName;
    private String pagePic;
}

class Post {

    private String post_id;

    @SerializedName("actor_id") // <- example SerializedName
    private String actorId;

    private String picOfPersonWhoPosted;
    private String nameOfPersonWhoPosted;
    private String message;
    private String likesCount;
    private ArrayList<String> comments;
    private String timeOfPost;
}

Rozbiór gramatyczny zdania

Teraz możesz parsować za pomocą biblioteki Gson:

MyModel model = gson.fromJson(jsonString, MyModel.class);

Importuj stopniowo

Pamiętaj, aby zaimportować bibliotekę z pliku Gradle aplikacji

implementation 'com.google.code.gson:gson:2.8.6' // or earlier versions

Automatyczne generowanie modelu

Możesz wygenerować model z JSON automatycznie przy użyciu narzędzi online takich jak ten .

lubilis
źródło
38

Prawie wszystkie udzielone odpowiedzi wymagają pełnej deserializacji JSON w obiekt Java przed uzyskaniem dostępu do wartości we właściwości będącej przedmiotem zainteresowania. Inną alternatywą, która nie idzie tą drogą, jest użycie JsonPATH, która jest jak XPath dla JSON i umożliwia przechodzenie obiektów JSON.

Jest to specyfikacja, a dobrzy ludzie z JayWay stworzyli implementację Java dla specyfikacji, którą można znaleźć tutaj: https://github.com/jayway/JsonPath

Więc w zasadzie, aby go użyć, dodaj go do swojego projektu, np .:

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>${version}</version>
</dependency>

i użyć:

String pageName = JsonPath.read(yourJsonString, "$.pageInfo.pageName");
String pagePic = JsonPath.read(yourJsonString, "$.pageInfo.pagePic");
String post_id = JsonPath.read(yourJsonString, "$.pagePosts[0].post_id");

itp...

Sprawdź stronę specyfikacji JsonPath, aby uzyskać więcej informacji na temat innych sposobów przejścia na JSON.

Dade
źródło
To bardzo dobra biblioteka, szczególnie do czytania i aktualizacji JSON, ale uważaj na znane problemy dotyczące tej biblioteki. Zobacz [1]: github.com/json-path/JsonPath/issues/272 [2]: github.com/json-path/JsonPath/issues/375
papigee
38

A - Wyjaśnienie

Można użyć bibliotek Jacksona do powiązania ciągu JSON z instancjami POJO ( Plain Old Java Object ). POJO to po prostu klasa z tylko prywatnymi polami i publicznymi metodami getter / setter. Jackson będzie przeglądał metody (przy użyciu odbicia ) i mapuje obiekt JSON na instancję POJO, ponieważ nazwy pól klasy pasują do nazw pól obiektu JSON.

W obiekcie JSON, który jest w rzeczywistości obiektem złożonym , główny obiekt składa się z dwóch podobiektów. Zatem nasze klasy POJO powinny mieć tę samą hierarchię. Wywołam cały obiekt JSON jako obiekt strony . Obiekt strony składa się z obiektu PageInfo i tablicy obiektów Post .

Musimy więc stworzyć trzy różne klasy POJO;

  • Page Class, złożony z PageInfo Class i tablicy instancji Post
  • PageInfo Class
  • Klasa postów

Jedynym pakietem, z którego korzystałem, jest Jackson ObjectMapper, a my wiążemy dane;

com.fasterxml.jackson.databind.ObjectMapper

Wymagane zależności, pliki jar są wymienione poniżej;

  • jackson-core-2.5.1.jar
  • jackson-databind-2.5.1.jar
  • jackson-annotations-2.5.0.jar

Oto wymagany kod;

B - Główna klasa POJO: strona

package com.levo.jsonex.model;

public class Page {

    private PageInfo pageInfo;
    private Post[] posts;

    public PageInfo getPageInfo() {
        return pageInfo;
    }

    public void setPageInfo(PageInfo pageInfo) {
        this.pageInfo = pageInfo;
    }

    public Post[] getPosts() {
        return posts;
    }

    public void setPosts(Post[] posts) {
        this.posts = posts;
    }

}

C - Klasa POJO podrzędna: PageInfo

package com.levo.jsonex.model;

public class PageInfo {

    private String pageName;
    private String pagePic;

    public String getPageName() {
        return pageName;
    }

    public void setPageName(String pageName) {
        this.pageName = pageName;
    }

    public String getPagePic() {
        return pagePic;
    }

    public void setPagePic(String pagePic) {
        this.pagePic = pagePic;
    }

}

D - Dziecko POJO Klasa: Poczta

package com.levo.jsonex.model;

public class Post {

    private String post_id;
    private String actor_id;
    private String picOfPersonWhoPosted;
    private String nameOfPersonWhoPosted;
    private String message;
    private int likesCount;
    private String[] comments;
    private int timeOfPost;

    public String getPost_id() {
        return post_id;
    }

    public void setPost_id(String post_id) {
        this.post_id = post_id;
    }

    public String getActor_id() {
        return actor_id;
    }

    public void setActor_id(String actor_id) {
        this.actor_id = actor_id;
    }

    public String getPicOfPersonWhoPosted() {
        return picOfPersonWhoPosted;
    }

    public void setPicOfPersonWhoPosted(String picOfPersonWhoPosted) {
        this.picOfPersonWhoPosted = picOfPersonWhoPosted;
    }

    public String getNameOfPersonWhoPosted() {
        return nameOfPersonWhoPosted;
    }

    public void setNameOfPersonWhoPosted(String nameOfPersonWhoPosted) {
        this.nameOfPersonWhoPosted = nameOfPersonWhoPosted;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getLikesCount() {
        return likesCount;
    }

    public void setLikesCount(int likesCount) {
        this.likesCount = likesCount;
    }

    public String[] getComments() {
        return comments;
    }

    public void setComments(String[] comments) {
        this.comments = comments;
    }

    public int getTimeOfPost() {
        return timeOfPost;
    }

    public void setTimeOfPost(int timeOfPost) {
        this.timeOfPost = timeOfPost;
    }

}

E - Przykładowy plik JSON: sampleJSONFile.json

Właśnie skopiowałem twoją próbkę JSON do tego pliku i umieściłem ją w folderze projektu.

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    },
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": "1234567890",
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": "2",
              "comments": [],
              "timeOfPost": "1234567890"
         }
    ]
}

F - Kod demonstracyjny

package com.levo.jsonex;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.levo.jsonex.model.Page;
import com.levo.jsonex.model.PageInfo;
import com.levo.jsonex.model.Post;

public class JSONDemo {

    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();

        try {
            Page page = objectMapper.readValue(new File("sampleJSONFile.json"), Page.class);

            printParsedObject(page);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void printParsedObject(Page page) {
        printPageInfo(page.getPageInfo());
        System.out.println();
        printPosts(page.getPosts());
    }

    private static void printPageInfo(PageInfo pageInfo) {
        System.out.println("Page Info;");
        System.out.println("**********");
        System.out.println("\tPage Name : " + pageInfo.getPageName());
        System.out.println("\tPage Pic  : " + pageInfo.getPagePic());
    }

    private static void printPosts(Post[] posts) {
        System.out.println("Page Posts;");
        System.out.println("**********");
        for(Post post : posts) {
            printPost(post);
        }
    }

    private static void printPost(Post post) {
        System.out.println("\tPost Id                   : " + post.getPost_id());
        System.out.println("\tActor Id                  : " + post.getActor_id());
        System.out.println("\tPic Of Person Who Posted  : " + post.getPicOfPersonWhoPosted());
        System.out.println("\tName Of Person Who Posted : " + post.getNameOfPersonWhoPosted());
        System.out.println("\tMessage                   : " + post.getMessage());
        System.out.println("\tLikes Count               : " + post.getLikesCount());
        System.out.println("\tComments                  : " + Arrays.toString(post.getComments()));
        System.out.println("\tTime Of Post              : " + post.getTimeOfPost());
    }

}

G - Wyjście demonstracyjne

Page Info;
****(*****
    Page Name : abc
    Page Pic  : http://example.com/content.jpg
Page Posts;
**********
    Post Id                   : 123456789012_123456789012
    Actor Id                  : 1234567890
    Pic Of Person Who Posted  : http://example.com/photo.jpg
    Name Of Person Who Posted : Jane Doe
    Message                   : Sounds cool. Can't wait to see it!
    Likes Count               : 2
    Comments                  : []
    Time Of Post              : 1234567890
Levent Divilioglu
źródło
26

Użyj minimal-json, który jest bardzo szybki i łatwy w użyciu. Możesz analizować z String obj i Stream.

Przykładowe dane:

{
  "order": 4711,
  "items": [
    {
      "name": "NE555 Timer IC",
      "cat-id": "645723",
      "quantity": 10,
    },
    {
      "name": "LM358N OpAmp IC",
      "cat-id": "764525",
      "quantity": 2
    }
  ]
}

Rozbiór gramatyczny zdania:

JsonObject object = Json.parse(input).asObject();
int orders = object.get("order").asInt();
JsonArray items = object.get("items").asArray();

Tworzenie JSON:

JsonObject user = Json.object().add("name", "Sakib").add("age", 23);

Maven:

<dependency>
  <groupId>com.eclipsesource.minimal-json</groupId>
  <artifactId>minimal-json</artifactId>
  <version>0.9.4</version>
</dependency>
Sakib Sami
źródło
Jak będzie wyglądać pojęcie?
Jesse
Do Pojo użyj gson. Ta biblioteka nie obsługuje.
Sakib Sami
22

Uważam, że najlepszą praktyką powinno być przejrzenie oficjalnego API JSON Java, które wciąż są w toku.

Giovanni Botta
źródło
7
Odkąd odpowiedziałem, zacząłem używać Jacksona i myślę, że jest to jedna z najlepszych bibliotek do deserializacji JSON.
Giovanni Botta,
2
Dlaczego ponownie używają JSONP, aby oznaczać coś innego niż JSON z Padding ? ...
Chris Wesseling
@ChrisWesseling Co masz na myśli?
Giovanni Botta
„Java API for JSON Processing (JSON-P)” to tytuł dokumentu, do którego prowadzi łącze. I wprawiło mnie to w zakłopotanie, ponieważ wiedziałem, że JSONP ma na myśli coś innego.
Chris Wesseling
1
@ChrisWesseling oh, to mylące. Właśnie to wybrali do specyfikacji. Jednak, jak powiedziałem, pojechałbym prosto do Jacksona.
Giovanni Botta
22

Ponieważ nikt jeszcze o tym nie wspominał, oto początek rozwiązania wykorzystującego Nashorn (środowisko wykonawcze JavaScript w Javie 8, ale przestarzałe w Javie 11).

Rozwiązanie

private static final String EXTRACTOR_SCRIPT =
    "var fun = function(raw) { " +
    "var json = JSON.parse(raw); " +
    "return [json.pageInfo.pageName, json.pageInfo.pagePic, json.posts[0].post_id];};";

public void run() throws ScriptException, NoSuchMethodException {
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
    engine.eval(EXTRACTOR_SCRIPT);
    Invocable invocable = (Invocable) engine;
    JSObject result = (JSObject) invocable.invokeFunction("fun", JSON);
    result.values().forEach(e -> System.out.println(e));
}

Porównanie wydajności

Napisałem treść JSON zawierającą trzy tablice zawierające odpowiednio 20, 20 i 100 elementów. Chcę tylko uzyskać 100 elementów z trzeciej tablicy. Korzystam z następującej funkcji JavaScript do analizowania i pobierania moich wpisów.

var fun = function(raw) {JSON.parse(raw).entries};

Wykonanie połączenia milion razy za pomocą Nashorn zajmuje 7,5 ~ 7,8 sekundy

(JSObject) invocable.invokeFunction("fun", json);

org.json zajmuje 20 ~ 21 sekund

new JSONObject(JSON).getJSONArray("entries");

Jackson zajmuje 6,5 ~ 7 sekund

mapper.readValue(JSON, Entries.class).getEntries();

W tym przypadku Jackson radzi sobie lepiej niż Nashorn, który działa znacznie lepiej niż org.json. Nashorn API jest trudniejszy w użyciu niż org.json's lub Jackson's. W zależności od wymagań Jackson i Nashorn oba mogą być realnym rozwiązaniem.

otonglet
źródło
1
Jaka jest jednostka „ "”? Nie cale? Czy to sekundy? Minuty?
Peter Mortensen
1
@PeterMortensen oznacza sekundy. Ponieważ wydaje się niejasne, zmienię to. Dzięki za recenzję.
otonglet
2
Niestety, Nashorn jest przestarzały w Javie 11. JEP 335 .
Per Mildner,
1
Wiem, że Nashorn jest przestarzała, ale podobała mi się ta odpowiedź, ponieważ nie chciałem żadnych zależności; jednak miałem do ponownej pracy przykład trochę:ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); engine.eval("var fun = function(raw) { return JSON.parse(raw); };"); Map<String, Object> json = (Map<String, Object>) ((Invocable) engine).invokeFunction("fun", jsonString);
kgibm
21

Poniższy przykład pokazuje, jak czytać tekst w pytaniu, reprezentowany jako zmienna „jsonText”. To rozwiązanie wykorzystuje interfejs API Java EE7 javax.json (który jest wymieniony w niektórych innych odpowiedziach). Powodem dodania go jako oddzielnej odpowiedzi jest to, że poniższy kod pokazuje, jak faktycznie uzyskać dostęp do niektórych wartości pokazanych w pytaniu. W celu uruchomienia tego kodu wymagana będzie implementacja interfejsu API javax.json . Dołączono pełny pakiet dla każdej wymaganej klasy, ponieważ nie chciałem deklarować instrukcji „import”.

javax.json.JsonReader jr = 
    javax.json.Json.createReader(new StringReader(jsonText));
javax.json.JsonObject jo = jr.readObject();

//Read the page info.
javax.json.JsonObject pageInfo = jo.getJsonObject("pageInfo");
System.out.println(pageInfo.getString("pageName"));

//Read the posts.
javax.json.JsonArray posts = jo.getJsonArray("posts");
//Read the first post.
javax.json.JsonObject post = posts.getJsonObject(0);
//Read the post_id field.
String postId = post.getString("post_id");

Teraz, zanim ktokolwiek przejdzie i zlekceważy tę odpowiedź, ponieważ nie używa GSON, org.json, Jackson ani żadnego z innych dostępnych frameworków innych firm, jest to przykład „wymaganego kodu” na pytanie, aby przeanalizować podany tekst. Jestem w pełni świadomy, że przestrzeganie obecnego standardu JSR 353 nie było brane pod uwagę dla JDK 9 i jako takie specyfikację JSR 353 należy traktować tak samo, jak każdą inną implementację obsługi JSON innej firmy.

justin.hughey
źródło
15

To zadziwiło mnie, jak łatwo było. Możesz po prostu przekazać Stringtrzymający JSON konstruktorowi JSONObject w domyślnym pakiecie org.json.

JSONArray rootOfPage =  new JSONArray(JSONString);

Gotowy. Zrzuca mikrofon . Działa to JSONObjectsrównież z. Następnie możesz po prostu przejrzeć swoją hierarchię Objectskorzystania z get()metod na obiektach.

brainmurphy1
źródło
13
Ten JSONArraytyp nie jest częścią interfejsu API JDSE J2SE i nie wiadomo, który interfejs API lub biblioteka innej firmy udostępnia ten typ.
Bobulous
2
Nie to, że polecam korzystanie z niego, ale myślę, że odnosi się to do pakietu „org.json” z json.org/java . Kiedyś był używany, zanim dobre biblioteki Java stały się dostępne, ale to było lata temu (2008 lub wcześniej)
StaxMan
1
Czy może brainmurphy1 oznacza JSONArray w systemie Android?
Alexander Farber
12

Istnieje wiele bibliotek JSON dostępnych w Javie.

Najbardziej znane to: Jackson, GSON, Genson, FastJson i org.json.

Zazwyczaj przy wyborze dowolnej biblioteki należy zwrócić uwagę na trzy rzeczy:

  1. Wydajność
  2. Łatwość użycia (kod jest prosty do napisania i czytelny) - to idzie w parze z funkcjami.
  3. W przypadku aplikacji mobilnych: zależność / rozmiar słoika

W szczególności w bibliotekach JSON (i wszelkich bibliotekach serializacji / deserializacji) wiązanie danych jest również zwykle interesujące, ponieważ eliminuje potrzebę pisania kodu płyty kotłowej do pakowania / rozpakowywania danych.

Dla 1 zobacz ten test porównawczy: https://github.com/fabienrenaud/java-json-benchmark Zrobiłem przy użyciu JMH, który porównuje (jackson, gson, genson, fastjson, org.json, jsonp) wydajność serializatorów i deserializatorów za pomocą streamu i interfejsy API dla danych. Dla 2 osób można znaleźć liczne przykłady w Internecie. Powyższy punkt odniesienia można również wykorzystać jako źródło przykładów ...

Szybki start benchmarku: Jackson radzi sobie od 5 do 6 razy lepiej niż org.json i ponad dwukrotnie lepiej niż GSON.

W twoim przykładzie następujący kod dekoduje twój plik Json za pomocą Jacksona:

public class MyObj {

    private PageInfo pageInfo;
    private List<Post> posts;

    static final class PageInfo {
        private String pageName;
        private String pagePic;
    }

    static final class Post {
        private String post_id;
        @JsonProperty("actor_id");
        private String actorId;
        @JsonProperty("picOfPersonWhoPosted")
        private String pictureOfPoster;
        @JsonProperty("nameOfPersonWhoPosted")
        private String nameOfPoster;
        private String likesCount;
        private List<String> comments;
        private String timeOfPost;
    }

    private static final ObjectMapper JACKSON = new ObjectMapper();
    public static void main(String[] args) throws IOException {
        MyObj o = JACKSON.readValue(args[0], MyObj.class); // assumes args[0] contains your json payload provided in your question.
    }
}

Daj mi znać, jeśli masz jakieś pytania.

fabien
źródło
11

Oprócz innych odpowiedzi polecam ten internetowy serwis jsonschema2pojo.org do szybkiego generowania klas Java ze schematu json lub json dla GSON, Jackson 1.x lub Jackson 2.x. Na przykład, jeśli masz:

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    }
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": 1234567890,
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": 2,
              "comments": [],
              "timeOfPost": 1234567890
         }
    ]
}

Jsonschema2pojo.org dla GSON generowane:

@Generated("org.jsonschema2pojo")
public class Container {
    @SerializedName("pageInfo")
    @Expose
    public PageInfo pageInfo;
    @SerializedName("posts")
    @Expose
    public List<Post> posts = new ArrayList<Post>();
}

@Generated("org.jsonschema2pojo")
public class PageInfo {
    @SerializedName("pageName")
    @Expose
    public String pageName;
    @SerializedName("pagePic")
    @Expose
    public String pagePic;
}

@Generated("org.jsonschema2pojo")
public class Post {
    @SerializedName("post_id")
    @Expose
    public String postId;
    @SerializedName("actor_id")
    @Expose
    public long actorId;
    @SerializedName("picOfPersonWhoPosted")
    @Expose
    public String picOfPersonWhoPosted;
    @SerializedName("nameOfPersonWhoPosted")
    @Expose
    public String nameOfPersonWhoPosted;
    @SerializedName("message")
    @Expose
    public String message;
    @SerializedName("likesCount")
    @Expose
    public long likesCount;
    @SerializedName("comments")
    @Expose
    public List<Object> comments = new ArrayList<Object>();
    @SerializedName("timeOfPost")
    @Expose
    public long timeOfPost;
}
Wiaczesław Wedenin
źródło
9

Jeśli masz klasę Java (na przykład Wiadomość) reprezentującą ciąg JSON (jsonString), możesz użyć biblioteki Jackson JSON z:

Message message= new ObjectMapper().readValue(jsonString, Message.class);

a z obiektu wiadomości możesz pobrać dowolny jego atrybut.

Shailendra Singh
źródło
9

Gson jest łatwy do opanowania i wdrożenia, musimy wiedzieć, że stosujemy dwie metody

  • toJson () - Konwertuj obiekt Java na format JSON

  • fromJson () - Konwertuj JSON na obiekt Java

`

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import com.google.gson.Gson;

public class GsonExample {
    public static void main(String[] args) {

    Gson gson = new Gson();

    try {

        BufferedReader br = new BufferedReader(
            new FileReader("c:\\file.json"));

        //convert the json string back to object
        DataObject obj = gson.fromJson(br, DataObject.class);

        System.out.println(obj);

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

    }
}

`

venkat
źródło
Aby uzyskać pełną wiedzę na temat Gson, zapoznaj się z poniższymi linkami. github.com/google/gson/blob/master/UserGuide.md
venkat
9

Istnieje wiele bibliotek typu open source do analizowania zawartości JSON na obiekcie lub po prostu do odczytu wartości JSON. Wymagane jest jedynie odczytanie wartości i parsowanie ich do obiektu niestandardowego. Więc biblioteka org.json jest wystarczająca w twoim przypadku.

Użyj biblioteki org.json, aby ją przeanalizować i utworzyć JsonObject:

JSONObject jsonObj = new JSONObject(<jsonStr>);

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

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

Pełny przykład możesz zobaczyć tutaj:

Jak parsować JSON w Javie

lalitbhagtani
źródło
Wygląda na to, że wszystkie twoje odpowiedzi zawierają link do tej strony. Jeśli to spam, przestań. Jeśli tak nie jest, przepraszam za zamieszanie, ale nie sądzę, że konieczne jest opublikowanie linku we wszystkich twoich odpowiedziach.
Kaczor Donald
1
Trudno jest udzielić odpowiedzi, w której można wyjaśnić wszystkie scenariusze. Jak w tym przypadku, jak odczytać tablicę Json lub wiele obiektów Json. Nawet jeśli to zrobię, odpowiedź byłaby bardzo długa i człowiek może się pomylić. Podaję więc link, w którym podane jest właściwe wyjaśnienie, wraz z odpowiednim przykładem. Może wybrać wizytę lub może użyć tylko mojego wyjaśnienia.
lalitbhagtani
1
Wydaje mi się, że podany przez ciebie link pokazuje tylko, jak czytać JSON. Gdzie mogę znaleźć informacje o tym, jak JSON?
Lampros Tzanetos
Przepraszam, ale nie zrozumiałem twojego pytania: - „jak również JSON”
lalitbhagtani
7

Zrób coś takiego:

JSONParser jsonParser = new JSONParser();
JSONObject obj = (JSONObject) jsonParser.parse(contentString);
String product = (String) jsonObject.get("productId");
Sreekanth
źródło
10
Er, która to biblioteka?
Stewart
2
Myślę, że używa org.json.simple
Lasitha Yapa
7

Możesz użyć biblioteki Gson, aby przeanalizować ciąg JSON.

Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(jsonAsString, JsonObject.class);

String pageName = jsonObject.getAsJsonObject("pageInfo").get("pageName").getAsString();
String pagePic = jsonObject.getAsJsonObject("pageInfo").get("pagePic").getAsString();
String postId = jsonObject.getAsJsonArray("posts").get(0).getAsJsonObject().get("post_id").getAsString();

Możesz także zapętlić tablicę „postów” w następujący sposób:

JsonArray posts = jsonObject.getAsJsonArray("posts");
for (JsonElement post : posts) {
  String postId = post.getAsJsonObject().get("post_id").getAsString();
  //do something
}
LittleBigUllah
źródło
5
{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    },
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": "1234567890",
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": "2",
              "comments": [],
              "timeOfPost": "1234567890"
         }
    ]
}

Java code :

JSONObject obj = new JSONObject(responsejsonobj);
String pageName = obj.getJSONObject("pageInfo").getString("pageName");

JSONArray arr = obj.getJSONArray("posts");
for (int i = 0; i < arr.length(); i++)
{
    String post_id = arr.getJSONObject(i).getString("post_id");
    ......etc
}
LReddy
źródło
9
Wyjaśnij swoją odpowiedź, ponieważ odpowiedzi tylko na kod pomagają innym znacznie gorzej niż dobrze udokumentowanemu kodowi. Zobacz: „daj człowiekowi rybę, a nakarmisz go na jeden dzień; naucz mężczyznę łowić ryby, a karmisz go na całe życie” .
Wai Ha Lee
Warto wspomnieć, że jest to biblioteka lib 'org.json'. Jednak nie sądzę, że jest to dobry sposób na to, aby w ogóle być bardzo gadatliwym, a sama biblioteka „org.json” jest przestarzała (powolne, nieporęczne API). Istnieją lepsze wybory: GSON, Jackson, Boon, Genson do użycia.
StaxMan,
5

Przeczytaj następujący post na blogu, JSON w Javie .

Ten post jest trochę stary, ale wciąż chcę odpowiedzieć na twoje pytanie.

Krok 1: Utwórz klasę POJO swoich danych.

Krok 2: Teraz utwórz obiekt za pomocą JSON.

Employee employee = null;
ObjectMapper mapper = new ObjectMapper();
try{
    employee =  mapper.readValue(newFile("/home/sumit/employee.json"), Employee.class);
} 
catch (JsonGenerationException e){
    e.printStackTrace();
}

Więcej informacji można znaleźć pod następującym linkiem .

sumit kumar
źródło
4

Najlepsze odpowiedzi na tej stronie wykorzystują zbyt proste przykłady, takie jak obiekt z jedną właściwością (np. {Nazwa: wartość}). Myślę, że ten prosty, ale prawdziwy przykład może komuś pomóc.

Oto JSON zwrócony przez Google Translate API:

{
  "data": 
     {
        "translations": 
          [
            {
              "translatedText": "Arbeit"
             }
          ]
     }
}

Chcę odzyskać wartość atrybutu „przetłumaczony tekst”, np. „Arbeit” za pomocą Google'a Gson.

Dwa możliwe podejścia:

  1. Pobierz tylko jeden potrzebny atrybut

    String json  = callToTranslateApi("work", "de");
    JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
    return jsonObject.get("data").getAsJsonObject()
            .get("translations").getAsJsonArray()
            .get(0).getAsJsonObject()
            .get("translatedText").getAsString();
  2. Utwórz obiekt Java z JSON

    class ApiResponse {
        Data data;      
        class Data {
            Translation[] translations;         
            class Translation {
                String translatedText;
            }
         }
     }

    ...

     Gson g = new Gson();
     String json =callToTranslateApi("work", "de");
     ApiResponse response = g.fromJson(json, ApiResponse.class);
     return response.data.translations[0].translatedText;
yurin
źródło
4

Najpierw musisz wybrać bibliotekę implementacji, aby to zrobić.

API Java dla JSON przetwarzania (JSR 353) zapewnia przenośne API do analizowania, tworzenia, przekształcania i JSON zapytania przy użyciu modelu obiektowego i strumieniowego API.

Realizacja odniesienia jest tutaj: https://jsonp.java.net/

Tutaj znajdziesz listę wdrożeń JSR 353:

Jakie API implementuje JSR-353 (JSON)

I aby pomóc ci zdecydować ... Znalazłem również ten artykuł:

http://blog.takipi.com/the-ultimate-json-library-json-simple-vs-gson-vs-jackson-vs-json/

Jeśli zdecydujesz się na Jackson, oto dobry artykuł na temat konwersji między JSON na / z Java za pomocą Jacksona: https://www.mkyong.com/java/how-to-convert-java-object-to-from-json- jackson /

Mam nadzieję, że to pomoże!

Jose Manuel Gomez Alvarez
źródło
Wskazujesz na wersję 1 biblioteki Jackson. Zdecydowanie zalecamy użycie bieżącej wersji biblioteki Jacksona.
Herbert Yu,
4

Możesz użyć Jayway JsonPath . Poniżej znajduje się link GitHub z kodem źródłowym, szczegółami pom i dobrą dokumentacją.

https://github.com/jayway/JsonPath

Wykonaj poniższe kroki.

Krok 1 : Dodaj zależność Jyway JSON do ścieżki klasy w Maven lub pobierz plik JAR i dodaj go ręcznie.

<dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>2.2.0</version>
</dependency>

Krok 2 : Zapisz wejściowy JSON jako plik dla tego przykładu. W moim przypadku zapisałem twój JSON jako sampleJson.txt. Pamiętaj, że przegapiłeś przecinek między pageInfo a postami.

Krok 3 : Odczytaj zawartość JSON z powyższego pliku za pomocą bufferedReader i zapisz jako String.

BufferedReader br = new BufferedReader(new FileReader("D:\\sampleJson.txt"));

        StringBuilder sb = new StringBuilder();
        String line = br.readLine();

        while (line != null) {
            sb.append(line);
            sb.append(System.lineSeparator());
            line = br.readLine();
        }
        br.close();
        String jsonInput = sb.toString();

Krok 4 : Przetwarzaj swój ciąg JSON za pomocą analizatora JSON jayway.

Object document = Configuration.defaultConfiguration().jsonProvider().parse(jsonInput);

Krok 5 : Przeczytaj szczegóły jak poniżej.

String pageName = JsonPath.read(document, "$.pageInfo.pageName");
String pagePic = JsonPath.read(document, "$.pageInfo.pagePic");
String post_id = JsonPath.read(document, "$.posts[0].post_id");

System.out.println("$.pageInfo.pageName " + pageName);
System.out.println("$.pageInfo.pagePic " + pagePic);
System.out.println("$.posts[0].post_id " + post_id);

Dane wyjściowe będą :

$.pageInfo.pageName = abc
$.pageInfo.pagePic = http://example.com/content.jpg
$.posts[0].post_id  = 123456789012_123456789012
Ravi Durairaj
źródło
3

Mam JSON taki:

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    }
}

Klasa Java

class PageInfo {

    private String pageName;
    private String pagePic;

    // Getters and setters
}

Kod do konwersji tego JSON na klasę Java.

    PageInfo pageInfo = JsonPath.parse(jsonString).read("$.pageInfo", PageInfo.class);

Maven

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.2.0</version>
</dependency>
Parth Solanki
źródło
2

Adnotacji Apache @Model można używać do tworzenia klas modeli Java reprezentujących strukturę plików JSON i używania ich do uzyskiwania dostępu do różnych elementów drzewa JSON . W przeciwieństwie do innych rozwiązań, to działa całkowicie bez odbicia i dlatego nadaje się do środowisk, w których odbicie jest niemożliwe lub wiąże się ze znacznym obciążeniem.

Istnieje przykładowy projekt Maven pokazujący użycie. Przede wszystkim określa strukturę:

@Model(className="RepositoryInfo", properties = {
    @Property(name = "id", type = int.class),
    @Property(name = "name", type = String.class),
    @Property(name = "owner", type = Owner.class),
    @Property(name = "private", type = boolean.class),
})
final class RepositoryCntrl {
    @Model(className = "Owner", properties = {
        @Property(name = "login", type = String.class)
    })
    static final class OwnerCntrl {
    }
}

a następnie wykorzystuje wygenerowane klasy RepositoryInfo i Owner w celu parsowania podanego strumienia wejściowego i pobrania określonych informacji, wykonując to:

List<RepositoryInfo> repositories = new ArrayList<>();
try (InputStream is = initializeStream(args)) {
    Models.parse(CONTEXT, RepositoryInfo.class, is, repositories);
}

System.err.println("there is " + repositories.size() + " repositories");
repositories.stream().filter((repo) -> repo != null).forEach((repo) -> {
    System.err.println("repository " + repo.getName() + 
        " is owned by " + repo.getOwner().getLogin()
    );
})

To jest to! Oprócz tego tutaj jest żywa istota pokazująca podobny przykład wraz z asynchroniczną komunikacją sieciową.

Jaroslav Tulach
źródło
2

jsoniter(jsoniterator) to stosunkowo nowa i prosta biblioteka json, zaprojektowana tak, aby była prosta i szybka. Wszystko, co musisz zrobić, aby dokonać deserializacji danych JSON, to

JsonIterator.deserialize(jsonData, int[].class);

gdzie jsonDatajest ciąg danych JSON.

Sprawdź oficjalną stronę internetową, aby uzyskać więcej informacji.

Pika the Wizard of the Whales
źródło
1

Możemy użyć klasy JSONObject do konwersji ciągu JSON na obiekt JSON i iteracji po obiekcie JSON. Użyj następującego kodu.

JSONObject jObj = new JSONObject(contents.trim());
Iterator<?> keys = jObj.keys();

while( keys.hasNext() ) {
  String key = (String)keys.next();
  if ( jObj.get(key) instanceof JSONObject ) {           
    System.out.println(jObj.getString(String key));
  }
}
kowal
źródło
2
To jest tylko Android
Ľubomír
To nie tylko Android: docs.oracle.com/javaee/7/api/javax/json/JsonObject.html
Dermot Canniffe
1
@DermotCanniffe to tylko Android.
user4020527,
1

Możesz użyć biblioteki parsowania strumienia DSM do parsowania złożonego dokumentu json i XML. DSM parsuje dane tylko raz i nie ładuje wszystkich danych do pamięci.

Powiedzmy, że mamy klasę Page, która dokonuje deserializacji danych Json.

Klasa strony

public class Page {
    private String pageName;
    private String pageImage;
    private List<Sting> postIds;

    // getter/setter

}

Utwórz plik yaml Mapping.

result:
  type: object     # result is array
  path: /posts
  fields:
    pageName:
        path: /pageInfo/pageName
    pageImage:
        path: /pageInfo/pagePic
    postIds:
      path: post_id
      type: array

Użyj DSM do wyodrębnienia pól.

DSM dsm=new DSMBuilder(new File("path-to-yaml-config.yaml")).create(Page.class);
Page page= (Page)dsm.toObject(new path-to-json-data.json");

zmienna strony zserializowana do json:

{
  "pageName" : "abc",
  "pageImage" : "http://example.com/content.jpg",
  "postIds" : [ "123456789012_123456789012" ]
}

DSM jest bardzo dobry dla złożonych plików Json i XML.

mfe
źródło
0

Możesz użyć JsonNodedo ustrukturyzowanej reprezentacji drzewa swojego łańcucha JSON. Jest to część wszechstronnej biblioteki Jacksona, która jest wszechobecna.

ObjectMapper mapper = new ObjectMapper();
JsonNode yourObj = mapper.readTree("{\"k\":\"v\"}");
slashron
źródło