Як розібрати JSON на Java


1048

У мене є наступний текст JSON. Як я можу розібрати його , щоб отримати значення pageName, pagePic, post_idі т.д.?

{
   "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"
         }
    ]
}

7
вбудовані java в бібліотеках JSON - це швидкий спосіб зробити це, але, на мій досвід, GSON - найкраща бібліотека для безболісного розбору JSON в POJO.
Іман Акбарі

16
Це перше високоголосне і захищене питання, відповіді якого я вважав найбільш заплутаним
Ріяфа Абдул Хамед

6
@JaysonMinard погодився. Попросили про втручання моди. Це дійсно має бути закрито. Я спочатку припускав (помилково), що не міг цього зробити, поки питання було захищено, тому я його захистив і зробив свою справу. Повторно захистить його зараз, щоб запобігти низьким відповідям на відповідь тощо, під час очікування моди.
Мена

4
"Це питання не показує жодних зусиль для дослідження" - Підказка кнопки Downvote
Жан-Франсуа Корбетт

Відповіді:


753

Бібліотека org.json проста у використанні. Приклад нижче:

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

Ви можете знайти більше прикладів з: Розбір JSON на Java

Завантажувана банка: http://mvnrepository.com/artifact/org.json/json


15
Я згоден з @StaxMan. Я просто спробував org.json, і це жахливо громіздко. Наприклад, це справді не грає зі стандартними типами колекції Java.
Кен Вільямс

7
@StaxMan Я б вибрав org.jsonінші бібліотеки для простого розбору JSON, навіть не дивлячись. Саме довідкову бібліотеку створив Дуглас Крокфорд (відкривач JSON).
Омар Аль-Ітаві

31
@OmarIthawi, це просто нерозумно. Це корекція концепції з незграбним API, неефективною реалізацією. Я думаю, що краще розглядати бібліотеки за власними достоїнствами, а не намагатися вивести якість з її видимості у авторів - Дуг досяг багато чого, але це насправді не змінює якостей конкретної ліб. 10 років тому це була єдина гра в місті, але відтоді було досягнуто багато позитивних успіхів. Це як Struts з json libs.
StaxMan

12
org.json - одна з найгірших бібліотек json. Перед вибором слід переглянути набір функцій та продуктивність наявних бібліотек json. Ось орієнтир, який я порівнював Джексон, gson, org.json, genson за допомогою JMH: github.com/fabienrenaud/java-json-benchmark . Джексон - явний переможець тут.
fabien

4
Ліцензія не включає жодних широко використовуваних ліцензій з відкритим кодом, а також має авторські права.
Крістіан Вільма

536

На приклад припустимо припустити, що у вас є клас Personіз лише a name.

private class Person {
    public String name;

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

Google GSON ( Maven )

Мій особистий фаворит щодо великої серіалізації / де-серіалізації об'єктів 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"}

Оновлення

Якщо ви хочете отримати один атрибут, ви можете легко це зробити і з бібліотекою Google:

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

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

Org.JSON ( Maven )

Якщо вам не потрібна десеріалізація об'єкта, а просто отримати атрибут, ви можете спробувати org.json ( або подивіться приклад GSON вище! )

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

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

Джексон ( Мейвен )

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

System.out.println(user.name); //John

16
Хороша відповідь. Одна пропозиція щодо незначного вдосконалення: і GSON, і Джексон також підтримують використання дерева JSON-представлення (для Джексона це JsonNodes, GSON має щось подібне). Можливо, добре показати фрагменти, оскільки це схоже на єдиний спосіб, який пропонує org.json.
StaxMan

Ще дві бібліотеки, які варто згадати (в інтересах повноти): json-simple та JSONP Oracle
Джейк Бейкмен

3
@NeonWarge, чому? Мені здається, що ця відповідь передбачає, що вже визначений клас Java, який містить точно такі ж поля, як і рядок JSON, не менше і нічого більше. Це досить сильне припущення.
Андреа Лацаротто

1
json-simple та jsonp від Oracle страшенно спрацьовують : github.com/fabienrenaud/java-json-benchmark Для продуктивності виберіть Джексона або dsljson.
fabien

GSON не підтримує динамічну фільтрацію полів на інших рівнях, крім кореневих!
Gangnus

102
  1. Якщо ви хочете створити об'єкт Java з JSON, і навпаки, використовуйте GSON або JACKSON сторони інших тощо.

    //from object to JSON 
    Gson gson = new Gson();
    gson.toJson(yourObject);
    
    // from JSON to object 
    yourObject o = gson.fromJson(JSONString,yourObject.class);
  2. Але якщо потрібно просто проаналізувати рядок JSON і отримати деякі значення (АБО створити рядок JSON з нуля, щоб надіслати по дроту), просто використовуйте jar JaveEE, який містить JsonReader, JsonArray, JsonObject тощо. Ви можете скачати реалізацію цього такі характеристики, як javax.json. За допомогою цих двох банок я можу розібрати json та використати значення.

    Ці API фактично відповідають моделі аналізу DML / 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");

4
@nondescript Якби я мав здогадуватися, я б сказав, що це було знято з огляду на те, що він не відповідає на питання оригіналу плаката: "Що таке потрібний код?" Відповіді, які були використані, надали фрагменти коду.
jewbix.cube

4
Примітка: Jackson та GSON підтримують стиль дерева та / або прив'язку карт / списків, тому не потрібно використовувати пакет Java EE (javax.json). javax.json не може запропонувати більше, ніж Джексон або GSON.
StaxMan

Я пропоную додати посилання на бібліотеку JavaEE.
Василь Бурк

72

швидкий аналізатор json дуже простий, гнучкий, дуже швидкий і настроюється. Спробуй це

Особливості:

  • Сумісний зі специфікацією JSON (RFC4627)
  • Високопродуктивний аналізатор JSON
  • Підтримує гнучкий / налаштований підхід до розбору
  • Налаштована перевірка пар ключів / значень будь-якої ієрархії JSON
  • Простий у використанні # Дуже невеликий слід
  • Підвищує розробників, дружніх і легко відстежувати винятки
  • Підключена спеціальна підтримка перевірки - Ключі / Значення можна перевірити, налаштувавши власні валідатори як і коли вони виникнуть
  • Підтримка і неперевірка підтримки парсера
  • Підтримка двох типів конфігурації (JSON / XML) для використання швидкого JSON валідаційного аналізатора
  • Потрібен JDK 1.5
  • Відсутність залежності від зовнішніх бібліотек
  • Підтримка покоління JSON шляхом серіалізації об'єктів
  • Підтримка вибору типу колекції під час розбору

Його можна використовувати так:

JsonParserFactory factory=JsonParserFactory.getInstance();
JSONParser parser=factory.newJsonParser();
Map jsonMap=parser.parseJson(jsonString);

3
Чи є в наявності javadoc?
jboi

24
Цей пакет не може обробляти порожні значення під час розбору. Наприклад: ... "description": "" ... кидає виняток
Іван

6
Я вирішив цю проблему (та багато інших) у code.google.com/p/quick-json/isissue/detail?id=11 Я сподіваюся, що автор надасть час, щоб виправити її в офіційному випуску.
noamik

8
З перерахованих функцій, нічого не відрізняється порівняно з іншими варіантами - і претензія на високоефективність нічого не підтримується; на відміну від більш зрілих бібліотек (Gson, Jackson, Genson, Boon), які включаються до таких еталонів , як github.com/eishay/jvm-serializers , github.com/novoj/JavaJsonPerformanceTest або developer.com/lang/jscript/… - я не бачили, щоб ця бібліотека була включена до тестів, або згадується про її широке використання.
StaxMan

26
Цей проект видається мертвим і, здається, більше не розміщується в центральному сховищі Мейвена.
8bitjunkie

40

Ви можете використовувати Google Gson .

Використовуючи цю бібліотеку, потрібно створити лише модель з такою ж структурою JSON. Потім модель автоматично заповнюється. Ви повинні викликати свої змінні як свої JSON-ключі або використовувати, @SerializedNameякщо ви хочете використовувати різні імена.

JSON

З вашого прикладу:

{
    "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"
        }
    ]
}

Модель

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

Розбір

Тепер ви можете розбирати за допомогою бібліотеки Gson:

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

Імпорт Gradle

Не забудьте імпортувати бібліотеку у файл програми Gradle

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

Автоматична генерація моделі

Ви можете створити модель з JSON автоматично з допомогою онлайн - інструментів , як це .


38

Майже всі наведені відповіді потребують повної десеріалізації JSON в об’єкт Java, перш ніж отримати доступ до значення у властивості, що цікавить. Інша альтернатива, яка не йде цим маршрутом, - це використовувати JsonPATH, що схоже на XPath для JSON і дозволяє проходити JSON-об'єкти.

Це специфікація, і хороші люди на JayWay створили реалізацію Java для специфікації, яку ви можете знайти тут: https://github.com/jayway/JsonPath

Тому в основному, щоб використовувати його, додайте його до свого проекту, наприклад:

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

і використовувати:

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

тощо ...

Перегляньте сторінку специфікації JsonPath для отримання додаткової інформації про інші способи поперек JSON.


Це дуже гарна бібліотека, особливо для читання та оновлення JSON, але остерігайтеся відомого питання про цю бібліотеку. Дивіться [1]: github.com/json-path/JsonPath/isissue/272 [2]: github.com/json-path/JsonPath/isissue/375
papigee

38

А - Пояснення

Ви можете використовувати бібліотеки Джексона для прив'язки рядка JSON до екземплярів POJO ( Plain Old Java Object ). POJO - це просто клас із лише приватними полями та публічними методами отримання та встановлення. Джексон збирається відміняти методи (використовуючи відображення ) і відображає об'єкт JSON в екземпляр POJO, оскільки назви полів класу підходять до імен полів об'єкта JSON.

У вашому об'єкті JSON, який є насправді складеним об'єктом, основний об'єкт складається з двох суб-об'єктів. Отже, наші класи POJO повинні мати однакову ієрархію. Я буду називати весь об’єкт JSON як об’єкт Page . Об'єкт сторінки складається з об'єкта PageInfo та масиву об'єктів Post .

Отже, ми повинні створити три різні класи POJO;

  • Page Class, складова класу PageInfo та масив поштових інстанцій
  • PageInfo клас
  • Клас постів

Єдиний пакет, який я використав, - це Jackson ObjectMapper, який ми робимо - це прив'язка даних;

com.fasterxml.jackson.databind.ObjectMapper

Необхідні залежності, файли jar перераховані нижче;

  • jackson-core-2.5.1.jar
  • jackson-databind-2.5.1.jar
  • jackson-анотації-2.5.0.jar

Тут необхідний код;

B - Основний клас POJO: Сторінка

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 - Дитячий клас POJO: 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 - Дитячий клас POJO: Пост

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 - зразок файлу JSON: sampleJSONFile.json

Я щойно скопіював ваш зразок JSON в цей файл і помістив його в папку проекту.

{
   "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 - Демо-код

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 - демонстраційний вихід

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

26

Використовуйте мінімальний json, який дуже швидкий і простий у використанні. Ви можете розібратися з String obj та Stream.

Приклад даних:

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

Розбір:

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

Створення 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>

Як буде виглядати піхо?
Джессі

Для Pojo використовуйте gson. Ця бібліотека не підтримує.
Сакіб Самі

22

Я вважаю, що найкращою практикою повинно бути проходження офіційного API Java JSON, який все ще працює.


7
З того часу, як я відповів, я почав використовувати Джексона, і я думаю, що це одна з найкращих бібліотек для десерталізації JSON.
Джованні Ботта

2
Чому вони використовують повторно JSONP для того, щоб означати щось інше, ніж JSON з Padding ? ...
Кріс Вессілінг

@ChrisWesseling Що ти маєш на увазі?
Джованні Ботта

"Java API для обробки JSON (JSON-P)" - це назва документа, на який ви посилаєтесь. І це мене збентежило, бо я знав, що JSONP означає щось інше.
Кріс Вессілінг

1
@ChrisWesseling о, це заплутано. Ось що вони обрали для специфікації. Однак, як я вже сказав, я б поїхав прямо до Джексона.
Джованні Ботта

22

Оскільки про це ніхто ще не згадував, ось початок рішення з використанням Nashorn (частина часу виконання Java Java 8, але застаріла в Java 11).

Рішення

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

Порівняння продуктивності

Я написав вміст JSON, що містить три масиви відповідно 20, 20 та 100 елементів. Я хочу лише отримати 100 елементів з третього масиву. Я використовую наступну функцію JavaScript для розбору та отримання своїх записів.

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

Виконання дзвінка мільйон разів за допомогою Nashorn займає 7,5 ~ 7,8 секунди

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

org.json займає 20 ~ 21 секунду

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

Джексону потрібно 6,5 ~ 7 секунд

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

У цьому випадку Джексон працює краще, ніж Нашорн, який виконує набагато краще, ніж org.json. Nashorn API складніше використовувати ніж org.json або Джексона. Залежно від ваших вимог, Джексон і Нашорн можуть бути прийнятними рішеннями.


1
Що таке одиниця " ""? Не дюйми? Це секунди? Хвилини?
Пітер Мортенсен

1
@PeterMortensen це означає секунди. Оскільки це здається незрозумілим, я його зміню. Дякуємо за відгук.
отонглет

2
На жаль, Нашорн застарілий на Java 11. JEP 335 .
Per Mildner

1
Я знаю, що Нашорн застарів, але мені сподобалась ця відповідь, тому що я не хотів ніяких залежностей; проте мені довелося трохи 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);
переробити

21

Наведений нижче приклад показує, як читати текст у запитанні, представлений у вигляді змінної "jsonText". У цьому рішенні використовується Java Java EE7 javax.json API (який згадується в деяких інших відповідях). Причина, яку я додав як окрему відповідь, полягає в тому, що наступний код показує, як насправді отримати доступ до деяких значень, показаних у питанні. Для запуску цього коду потрібна реалізація API javax.json . Повний пакет для кожного з необхідних класів був включений, оскільки я не хотів оголошувати "імпортні" заяви.

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

Тепер, перш ніж хтось відхилиться і скаже цю відповідь, оскільки вона не використовує GSON, org.json, Джексон або будь-яку з інших наявних фреймворків, це приклад "необхідного коду" за запитання для розбору наданого тексту. Мені добре відомо, що прихильність до діючого стандарту JSR 353 не розглядалася для JDK 9, і як такий специфікація JSR 353 повинна трактуватися так само, як і будь-яка інша реалізація JSON третьої сторони.


15

Це підірвало мою думку тим, як це було легко. Ви можете просто передати Stringутримуючий свій JSON конструктору JSONObject в пакеті org.json за замовчуванням.

JSONArray rootOfPage =  new JSONArray(JSONString);

Зроблено. Скидає мікрофон . Це працює і з цим JSONObjects. Після цього ви можете просто переглянути свою ієрархію Objectsвикористання get()методів на ваших об'єктах.


13
JSONArrayТип не є частиною API J2SE JDK і не сказати, API або бібліотеки сторонніх виробників забезпечує цей тип.
Bobulous

2
Не те, що я б рекомендував використовувати його, але я думаю, що це стосується пакету "org.json" від json.org/java . Він використовувався до того, як хороші бібліотеки Java стали доступними, але це було років тому (2008 або раніше)
StaxMan

1
Чи означає мозкова мурфія1 JSONArray в Android?
Олександр Фарбер

12

На Java існує багато бібліотек JSON.

Найвідоміші з них: Джексон, GSON, Генсон, FastJson та org.json.

Як правило, слід переглянути три речі, щоб вибрати будь-яку бібліотеку:

  1. Продуктивність
  2. Простота використання (код простий у написанні та розбірливості) - це в комплекті з функціями.
  3. Для мобільних додатків: залежність / розмір банку

Спеціально для бібліотек JSON (і будь-яких ліній серіалізації / десеріалізації), також пов'язане зв'язання даних також представляє інтерес, оскільки воно усуває необхідність написання кодового коду для упаковки / розпакування даних.

Для 1 дивіться цей орієнтир: https://github.com/fabienrenaud/java-json-benchmark Я робив за допомогою JMH, який порівнює (jackson, gson, genson, fastjson, org.json, jsonp) продуктивність серіалізаторів та десеріалізаторів за допомогою потоку і API зв’язування даних. Для 2 ви можете знайти численні приклади в Інтернеті. Наведений вище тест також може бути використаний як джерело прикладів ...

Швидкий винос еталону: Джексон працює в 5 - 6 разів краще, ніж org.json і більш ніж удвічі краще, ніж GSON.

Для вашого конкретного прикладу наступний код декодує ваш json з Джексоном:

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

Повідомте мене, якщо у вас є питання.


11

На додаток до інших відповідей, я рекомендую цю Інтернет-службу з відкритими ресурсами jsonschema2pojo.org для швидкого генерування класів Java з схеми json або json для GSON, Jackson 1.x або Jackson 2.x. Наприклад, якщо у вас є:

{
   "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 для GSON:

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

9

Якщо у вас є клас Java (скажімо Повідомлення), що представляє рядок JSON (jsonString), ви можете використовувати бібліотеку Jackson JSON з:

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

і з об’єкта повідомлення ви можете отримати будь-який його атрибут.


9

Gson легко вивчити та впровадити, що ми повинні знати, це наступні два методи

  • toJson () - Перетворення об’єкта Java у формат JSON

  • fromJson () - Перетворення JSON в об’єкт 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();
    }

    }
}

`


Для отримання повних знань про Gson див. Посилання нижче. github.com/google/gson/blob/master/UserGuide.md
venkat

9

Існує багато бібліотек з відкритим вихідним кодом, які аналізують вміст JSON на об'єкт або просто для читання значень JSON. Ваша вимога полягає лише в тому, щоб прочитати значення і проаналізувати їх на користувальницький об’єкт. Тож бібліотеки org.json у вашому випадку достатньо.

Використовуйте бібліотеку org.json для її розбору та створення JsonObject:

JSONObject jsonObj = new JSONObject(<jsonStr>);

Тепер використовуйте цей об’єкт, щоб отримати свої значення:

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

Повний приклад ви можете побачити тут:

Як розібрати JSON на Java


Схоже, всі ваші відповіді містять посилання на цей сайт. Якщо це спам, будь ласка, припиніть. Якщо це не так, вибачте за плутанину, але я не думаю, що потрібно розміщувати посилання у всіх ваших відповідях.
Дональд Дак

1
Важко дати відповідь, де можна пояснити всі сценарії. Як і в цьому випадку, як читати json масив або кілька об'єктів json. Навіть якщо я це роблю, відповідь буде дуже довгою, і людина може заплутатися. Тому я даю посилання, де дано належне пояснення, з належним прикладом. Він може обрати для відвідування або використовувати лише моє пояснення.
lalitbhagtani

1
Мені здається, що надане вами посилання лише демонструє, як читати JSON. Де я можу знайти інформацію про те, як зробити JSON?
Лампрос Цанетотос

Вибачте, але я не зрозумів вашого запитання: - "про те, як також JSON"
lalitbhagtani

7

Будь ласка, зробіть щось подібне:

JSONParser jsonParser = new JSONParser();
JSONObject obj = (JSONObject) jsonParser.parse(contentString);
String product = (String) jsonObject.get("productId");

10
Е, це бібліотека?
Стюарт

2
Я думаю, що він використовує org.json.simple
Lasitha Yapa

7

Ви можете використовувати бібліотеку Gson для розбору рядка 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();

Ви також можете переглядати масив "posts" так:

JsonArray posts = jsonObject.getAsJsonArray("posts");
for (JsonElement post : posts) {
  String postId = post.getAsJsonObject().get("post_id").getAsString();
  //do something
}

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
}

9
Будь-ласка, поясніть свою відповідь, оскільки відповіді, що стосуються лише коду, допомагають іншим значно менше, ніж добре задокументований код. Дивіться "дайте людині рибу, і ви її годуєте протягом дня; навчіть чоловіка ловити рибу, а ви годуєте його на все життя" .
Вай Ха Лі

Було б добре зазначити, що це для "org.json" lib. Однак я не думаю, що це зовсім не гарний спосіб зробити це дуже багатослівним, а сама "org.json" lib застаріла (повільний, громіздкий API). Є кращі варіанти: GSON, Джексон, Бун, Генсон, які слід використовувати.
StaxMan

5

Прочитайте наступну публікацію щоденника JSON на Java .

Цей пост трохи старий, але все ж я хочу відповісти на ваше запитання.

Крок 1. Створіть клас даних POJO зі своїх даних.

Крок 2: Тепер створіть об’єкт за допомогою JSON.

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

Для подальшого ознайомлення ви можете перейти за наступним посиланням .


4

Найпопулярніші відповіді на цій сторінці використовують занадто прості приклади, наприклад об’єкт з одним властивістю (наприклад, {name: value}). Я думаю, що все-таки простий, але реальний приклад може комусь допомогти.

Отже, це JSON, повернений API Google Translate:

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

Я хочу отримати значення атрибута "translationText", наприклад "Arbeit" за допомогою Gson Google.

Два можливі підходи:

  1. Отримайте лише один необхідний атрибут

    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. Створіть об’єкт Java від 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;

4

Спочатку для цього потрібно вибрати бібліотеку реалізації .

Java API для обробки JSON (JSR 353) забезпечує переносяться API - інтерфейси для синтаксичного аналізу, генерації, перетворення і JSON запитів з використанням об'єктної моделі і потокового API.

Еталонна реалізація тут: https://jsonp.java.net/

Тут ви можете знайти список реалізацій JSR 353:

Що таке API, який реалізує JSR-353 (JSON)

І щоб допомогти вам вирішити ... Я знайшов і цю статтю:

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

Якщо ви їдете на Джексона, ось хороша стаття про перетворення JSON в / з Java за допомогою Джексона: https://www.mkyong.com/java/how-to-convert-java-object-to-from-json- Джексон /

Сподіваюся, це допомагає!


Ви вказуєте на версію 1 бібліотеки Джексона. Настійно пропоную використовувати поточну версію бібліотеки Джексона.
Герберт Ю

4

Ви можете використовувати Jayway JsonPath . Нижче наводиться посилання GitHub із вихідним кодом, деталями пам’яті та хорошою документацією.

https://github.com/jayway/JsonPath

Дотримуйтесь наведених нижче кроків.

Крок 1 : Додайте залежність контуру JSON від шляху до класу за допомогою Maven або завантажте файл JAR та додайте його вручну.

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

Крок 2 : Будь ласка, збережіть свій вхідний JSON як файл для цього прикладу. У моєму випадку я зберег ваш JSON як sampleJson.txt. Зауважте, що ви пропустили кому між pageInfo та публікаціями.

Крок 3 : Прочитайте вміст JSON з вищевказаного файлу за допомогою bufferedReader та збережіть його як 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();

Крок 4 : Проаналізуйте рядок JSON за допомогою аналізатора Jyway JSON.

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

Крок 5 : Прочитайте деталі, як показано нижче.

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

Вихід буде :

$.pageInfo.pageName = abc
$.pageInfo.pagePic = http://example.com/content.jpg
$.posts[0].post_id  = 123456789012_123456789012

3

У мене JSON такий:

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

Клас Java

class PageInfo {

    private String pageName;
    private String pagePic;

    // Getters and setters
}

Код для перетворення цього JSON в клас Java.

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

Мейвен

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

2

Можна використовувати анотацію Apache @Model для створення модельних класів Java, що представляють структуру файлів JSON, і використовувати їх для доступу до різних елементів дерева JSON . На відміну від інших рішень, це працює повністю без роздумів і тому підходить для середовищ, де рефлексія неможлива або має значні надмірні витрати.

Є зразок проекту Maven, що показує використання. Перш за все це визначає структуру:

@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 {
    }
}

а потім він використовує створені класи RepositoryInfo та Owner, щоб проаналізувати наданий потік введення та вибрати певну інформацію, виконуючи це:

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

Це все! На додаток до цього, тут є історія, що показує подібний приклад разом з асинхронною мережевою комунікацією.


2

jsoniter(jsoniterator) - відносно нова і проста бібліотека json, призначена для простоти і швидкості. Все, що вам потрібно зробити, щоб дезаріалізувати дані json - це

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

де jsonDataрядок даних json.

Перегляньте офіційний веб-сайт для отримання додаткової інформації.


1

Ми можемо використовувати клас JSONObject для перетворення рядка JSON в об'єкт JSON та перетворення на об'єкт JSON. Використовуйте наступний код.

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

2
Це лише андроїд
Ľubomír


1
@DermotCanniffe це просто Android.
користувач4020527

1

Ви можете використовувати бібліотеку розбору потоку DSM для розбору складного json та XML-документа. Дані DSM аналізують лише один раз і не завантажують усі дані в пам'ять.

Скажімо, у нас є клас Page для десеріалізації даних даних json.

Клас сторінки

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

    // getter/setter

}

Створіть файл картографії yaml.

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

Використовуйте DSM для вилучення полів.

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

змінна сторінка, серіалізована в json:

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

DSM дуже хороший для складних json та xml.


0

Ви можете використовувати JsonNodeдля структурованого представлення дерева рядка JSON. Це частина бібліотеки рок-солідного Джексона, яка всюди присутня.

ObjectMapper mapper = new ObjectMapper();
JsonNode yourObj = mapper.readTree("{\"k\":\"v\"}");
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.