Как разобрать JSON в Java

1049

У меня есть следующий текст 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
Встроенные в JSON библиотеки java - это метод квикетов, но, по моему опыту, GSON - лучшая библиотека для безболезненного анализа JSON в POJO.
Иман Акбари
16
Это первый высоко защищенный вопрос, ответы на который я нашел наиболее запутанным
Рияфа Абдул Хамид
6
@JaysonMinard согласился. Попросил мод вмешательства. Это должно быть действительно закрыто. Сначала я предположил (ошибочно), что не смогу сделать это, пока вопрос защищен, поэтому снял защиту и сделал свое дело. Повторно защитил его сейчас, чтобы избежать ответов с низким уровнем повторения и тому подобного, пока ждал мод.
Мена
4
«Этот вопрос не требует каких-либо исследовательских усилий» - Подсказка по кнопке Downvote
Жан-Франсуа Корбетт
6
Этот вопрос обсуждается на Meta .
Марк Амери

Ответы:

755

Библиотека 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");
    ......
}

Вы можете найти больше примеров из: Parse JSON на Java

Загружаемый jar: http://mvnrepository.com/artifact/org.json/json

user1931858
источник
15
Я согласен с @StaxMan. Я только что попробовал org.json, и это ужасно громоздко. Например, он не работает со стандартными типами Java Collection.
Кен Уильямс
7
@StaxMan Я бы выбрал org.jsonдругие библиотеки для простого анализа JSON, даже не глядя. Это справочная библиотека, которую создал Дуглас Крокфорд (исследователь JSON).
Омар Аль-Итауи
31
@ OmarIthawi это просто глупо. Это подтверждение концепции с неуклюжим API, неэффективная реализация. Я думаю, что лучше рассматривать библиотеки по достоинству, а не пытаться вывести качество из видимости авторов - Даг достиг многого, но это не меняет качества конкретной библиотеки. 10 лет назад это была единственная игра в городе, но с тех пор был достигнут значительный прогресс. Это как Struts из JSON LIBS.
StaxMan
12
org.json - одна из худших библиотек json. Прежде чем выбирать, следует взглянуть на набор функций и производительность доступных библиотек json. Вот тест, который я сделал, сравнивая Джексона, Джсона, Органа, Дженсона, используя JMH: github.com/fabienrenaud/java-json-benchmark . Джексон - явный победитель здесь.
Фабиен
4
Лицензия не включает в себя какие-либо обычно используемые лицензии с открытым исходным кодом, а также имеет авторские права.
Кристиан Вьельма
538

Для примера давайте предположим, что у вас есть класс Personтолько с 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
SDekov
источник
16
Хороший ответ. Одно предложение для незначительного улучшения: и GSON, и Джексон также поддерживают использование представления дерева JSON (для Джексона это JsonNodes, GSON имеет нечто подобное). Может быть хорошо показывать фрагменты, так как это похоже на единственный способ, который предлагает org.json.
StaxMan
Стоит упомянуть еще две библиотеки (в интересах полноты): json-simple и Oracle JSONP
Джейк Стимман
3
@ NeonWarge, почему? Мне кажется, что этот ответ предполагает, что кто-то уже определил класс Java, который содержит точно такие же поля, что и строка JSON, ни меньше, ни больше. Это довольно сильное предположение.
Андреа Лаззаротто
1
json-simple и jsonp оракула работают ужасно: github.com/fabienrenaud/java-json-benchmark Для производительности выберите jackson или dsljson.
Фабьен
GSON не поддерживает динамическую фильтрацию полей на уровнях, отличных от root!
Гангнус
102
  1. Если вы хотите создать объект Java из JSON и наоборот, используйте GSON или JACKSON сторонние файлы jar и т. Д.

    //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 с нуля для отправки по проводам), просто используйте JaveEE jar, который содержит JsonReader, JsonArray, JsonObject и т. Д. Вы можете загрузить реализацию этого спецификация как javax.json. С этими двумя банками я могу проанализировать JSON и использовать значения.

    Эти API на самом деле следуют модели синтаксического анализа 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");
невзрачный
источник
4
@nondescript Если бы мне пришлось угадывать, я бы сказал, что за него проголосовали, потому что он не отвечает на вопрос оригинального автора: «Что такое требуемый код?» Ответы, которые были отклонены, предоставили фрагменты кода.
jewbix.cube
4
Примечание. Jackson и GSON поддерживают привязку в стиле дерева и / или привязку Maps / Lists, поэтому нет необходимости использовать пакет Java EE (javax.json). javax.json мало что может предложить помимо Джексона или GSON.
StaxMan
Я предлагаю добавить ссылку на библиотеку JavaEE.
Василий Бурк
72

Парсер quick-json очень простой, гибкий, очень быстрый и настраиваемый. Попробуй это

Особенности:

  • Соответствует спецификации JSON (RFC4627)
  • Высокопроизводительный анализатор JSON
  • Поддерживает гибкий / настраиваемый подход к анализу
  • Настраиваемая проверка пар ключ / значение любой иерархии JSON
  • Простота в использовании # Очень маленькая площадь
  • Повышает дружественный к разработчику и легко отслеживать исключения
  • Поддержка сменной настраиваемой проверки - ключи / значения можно проверять, настраивая настраиваемые средства проверки по мере их появления.
  • Поддержка валидации и недействительности парсера
  • Поддержка двух типов конфигурации (JSON / XML) для использования анализатора быстрой проверки JSON
  • Требуется JDK 1.5
  • Нет зависимости от внешних библиотек
  • Поддержка JSON Generation через сериализацию объектов
  • Поддержка выбора типа коллекции во время анализа

Это можно использовать так:

JsonParserFactory factory=JsonParserFactory.getInstance();
JSONParser parser=factory.newJsonParser();
Map jsonMap=parser.parseJson(jsonString);
rputta
источник
3
Доступен ли Javadoc?
2013 года
24
Этот пакет не может обрабатывать пустые значения при разборе. Например: ... "description": "" ... выдает исключение
Иван
6
Я исправил эту проблему (и многие другие) в code.google.com/p/quick-json/issues/detail?id=11. Надеюсь, автор даст время, чтобы исправить ее в официальном выпуске.
noamik
8
Из перечисленных функций ничто не является уникальным по сравнению с другими вариантами - и утверждение о высокой производительности ничем не поддерживается; в отличие от более зрелых библиотек (Gson, Jackson, Genson, Boon), которые включены в тесты, такие как github.com/eishay/jvm-serializers , github.com/novoj/JavaJsonPerformanceTest или developer.com/lang/jscript/… - I Я не видел эту библиотеку включенной в тесты или упоминания о ее широком использовании.
StaxMan
26
Этот проект кажется мертвым и, по-видимому, больше не размещается в центральном хранилище Maven.
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 автоматически с помощью онлайн - инструментов , как это .

lubilis
источник
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/issues/272 [2]: github.com/json-path/JsonPath/issues/375
папий
38

A - Объяснение

Вы можете использовать библиотеки Джексона для привязки JSON String к экземплярам POJO ( Plain Old Java Object ). POJO - это просто класс с только закрытыми полями и общедоступными методами получения / установки. Джексон собирается пересечь методы (используя отражение ) и отображает объект JSON в экземпляр POJO, когда имена полей класса соответствуют именам полей объекта JSON.

В вашем объекте JSON, который на самом деле является составным объектом, основной объект состоит из двух подобъектов. Итак, наши классы POJO должны иметь одинаковую иерархию. Я назову весь объект JSON как объект страницы . Объект Page состоит из объекта PageInfo и массива объектов Post .

Таким образом, мы должны создать три разных класса POJO;

  • Класс страницы , составная часть класса PageInfo и массив почтовых экземпляров
  • Класс PageInfo
  • Класс сообщений

Единственный пакет, который я использовал, это Jackson ObjectMapper, мы делаем привязку данных;

com.fasterxml.jackson.databind.ObjectMapper

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

  • ДЖЕКСОН-ядро-2.5.1.jar
  • ДЖЕКСОН-DataBind-2.5.1.jar
  • ДЖЕКСОН-аннотаций-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: Post

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

Используйте minimal-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?
Джесси
Для Pojo используйте gson. Эта библиотека не поддерживает.
Сакиб Сами
22

Я считаю, что лучшая практика должна состоять в том, чтобы пройти через официальный Java JSON API, который все еще находится в стадии разработки.

Джованни Ботта
источник
7
С тех пор как я ответил, я начал использовать Джексона, и я думаю, что это одна из лучших библиотек для десериализации JSON.
Джованни Ботта
2
Почему они повторно используют JSONP для обозначения чего-то иного, чем JSON в Padding ? ...
Крис Весселинг
@ChrisWesseling Что ты имеешь в виду?
Джованни Ботта
«Java API для обработки JSON (JSON-P)» - это название документа, на который вы ссылаетесь. И это смутило меня, потому что я знал, что JSONP означает что-то другое.
Крис Весселинг
1
@ChrisWesseling, это сбивает с толку. Это то, что они выбрали для спецификации. Однако, как я уже сказал, я бы пошел прямо к Джексону.
Джованни Ботта
22

Поскольку никто еще не упомянул об этом, вот начало решения с использованием Nashorn (JavaScript-часть 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();

В этом случае Джексон работает лучше, чем Nashorn, который работает намного лучше, чем org.json. API Nashorn сложнее в использовании, чем в org.json или Jackson's. В зависимости от ваших требований Джексон и Нашорн могут быть жизнеспособными решениями.

otonglet
источник
1
Что такое блок " ""? Не дюймов? Это секунды? Минуты?
Питер Мортенсен
1
@PeterMortensen это означает секунды. Поскольку это кажется неясным, я изменю это. Спасибо за обзор.
отонглет
2
К сожалению, Nashorn устарел в Java 11. JEP 335 .
За Милднер
1
Я знаю, что Nashorn устарел, но мне понравился этот ответ, потому что я не хотел никаких зависимостей; однако мне пришлось немного 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». В этом решении используется API Java EE7 javax.json (который упоминается в некоторых других ответах). Причина, по которой я добавил его в качестве отдельного ответа, заключается в том, что следующий код показывает, как на самом деле получить доступ к некоторым значениям, показанным в вопросе. Для выполнения этого кода потребуется реализация API javax.json . Полный пакет для каждого из необходимых классов был включен, так как я не хотел объявлять операторы 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");

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

justin.hughey
источник
15

Это поразило меня тем, как легко это было. Вы можете просто передать Stringудержание вашего JSON в конструктор JSONObject в стандартном пакете org.json.

JSONArray rootOfPage =  new JSONArray(JSONString);

Выполнено. Сбрасывает микрофон . Это работает JSONObjectsтакже. После этого вы можете просто просмотреть иерархию Objectsиспользования get()методов ваших объектов.

brainmurphy1
источник
13
JSONArrayТип не является частью API J2SE JDK и не сказать, API или библиотеки сторонних производителей обеспечивает этот тип.
Великолепно
2
Не то, чтобы я рекомендовал использовать его, но я думаю, что это относится к пакету "org.json" от json.org/java . Раньше он использовался до того, как стали доступны хорошие библиотеки Java, но это было много лет назад (2008 или ранее)
StaxMan
1
Или brainmurphy1 означает JSONArray в Android?
Александр Фарбер
12

В Java доступно много библиотек JSON.

Наиболее известные из них: Джексон, GSON, Genson, FastJson и org.json.

Как правило, есть три вещи, на которые следует обратить внимание при выборе любой библиотеки:

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

В частности, для библиотек JSON (и любых библиотек сериализации / десериализации) связывание данных также обычно представляет интерес, поскольку устраняет необходимость написания стандартного кода для упаковки / распаковки данных.

Для 1, смотрите этот тест: https://github.com/fabienrenaud/java-json-benchmark Я сделал с помощью JMH, который сравнивает (Джексон, 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 (скажем, Message), представляющий строку JSON (jsonString), вы можете использовать библиотеку JSON Jackson с:

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

    }
}

`

Venkat
источник
Для получения полной информации о 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

lalitbhagtani
источник
Кажется, что все ваши ответы содержат ссылку на этот сайт. Если это спам, пожалуйста, прекратите. Если это не так, извините за путаницу, но я не думаю, что необходимо размещать ссылку во всех ваших ответах.
Дональд Дак
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
Ласита Япа
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
}
LittleBigUllah
источник
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
источник
9
Пожалуйста, объясните свой ответ, так как ответы только для кода помогают другим гораздо меньше, чем хорошо документированный код. Смотрите: «дай человеку рыбу, и ты накормишь его на день; научи человека ловить рыбу, и ты накормишь его на всю жизнь» .
Вай Ха Ли
Было бы хорошо упомянуть, что это для lib 'org.json'. Однако я не думаю, что это хороший способ сделать это, будучи очень многословным, а сама библиотека org.json устарела (медленный, громоздкий 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, возвращаемый Google Translate API:

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

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

Два возможных подхода:

  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 с исходным кодом, подробностями о pom и хорошей документацией.

https://github.com/jayway/JsonPath

Пожалуйста, следуйте инструкциям ниже.

Шаг 1 : Добавьте зависимость пути JSON Jayway в путь к классу с помощью 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 с помощью Jayway JSON parser.

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
Это андроид только
Любомир
Это не только Android: docs.oracle.com/javaee/7/api/javax/json/JsonObject.html
Дермот Каннифф
1
@DermotCanniffe это просто Android.
user4020527
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.

MFE
источник
0

Вы можете использовать JsonNodeдля структурированного представления дерева вашей строки JSON. Это часть библиотеки Rock Solid Jackson, которая вездесуща.

ObjectMapper mapper = new ObjectMapper();
JsonNode yourObj = mapper.readTree("{\"k\":\"v\"}");
slashron
источник