четверг, 31 марта 2011 г.

Работа с JSON в Java

JSON (JavaScript Object Notation) - текстовый формат обмена данными, легко читаемый людьми и основанный на синтаксисе Javascript. JSON, как правило, используется с Javascript, если быть более точным - при обмене данными между Javascript и сервером. Стоит отметить, что JSON обладает существенным преимуществом перед XML - он менее избыточен.

Пример JSON объекта:

{
  userId: 32,
  firstName: "Алексей",
  lastName: "Голобурдин",
  address: {
    country: "Россия",
    city: "Москва"
  },
  phone: "8 (905) 777 77 77"
}

Как видно, все предельно просто. Фактически, JSON объект является валидным Javascript кодом, то есть может быть исполнен интерпретатором Javascript. Но как сгенерировать JSON на сервере, и как распарсить пришедший от клиента JSON?

PHP программисты сейчас довольно ухмыльнутся, ведь у них есть стандартные функции json_encode и json_decode, позволяющие легко и просто гонять PHP сущности в JSON и обратно.

Java программистам приходится сложнее - надо поддерживать свою крутость (где PHP - Personal HomePage language, и где крутая Enterprise Java), поэтому с JSON приходится работать путем сторонних библиотек, коих на офсайте json.org приводится немало. Программисты Python здесь тоже ухмыльнутся - их дзен "Должен быть только один, и лучше всего очевидный, способ сделать это".

Итак, в данной статье рассматривается использование отличной java библиотеки для генерирования и парсинга JSON - json-simple, официальный сайт на google code. Кстати, там можно найти немало отличных примеров!

Вот таблица сопоставления типов JSON и Java:

JSONJava
stringjava.lang.String
numberjava.lang.Number
true | falsejava.lang.Number
nullnull
arrayjava.util.List
objectjava.util.Map

Тааак, и как нам всем этим добром пользоваться?

Примеры давай, примеры!


Cоздадим JSON строку!

//import org.json.simple.JSONObject;
  
JSONObject resultJson = new JSONObject();

resultJson.put("name","foo");
resultJson.put("num",new Integer(100));
resultJson.put("is_vip",new Boolean(true));
resultJson.put("nickname",null);
System.out.print(obj.toString());
// {"name": "foo", "num": 100, "is_vip": true, "nickname: null}

Ну ладно, круто. А что-то посложнее?

JSONArray ar = new JSONArray();
JSONObject obj = new JSONObject();
JSONObject resultJson = new JSONObject();

ar.add("first");
ar.add(new Integer(100));

obj.put("one", "two");
obj.put("three", "four");

resultJson.put("paramsArray", ar);
resultJson.put("paramsObj", obj);
resultJson.put("paramsStr", "some string");
System.out.print(obj.toString());
// {"paramsArray": ["first", 100],
//  "paramsObj": {"one": "two", "three": "four"},
//  "paramsStr": "some string"}

Думаю, комментарии здесь излишни, все действительно чрезвычайно интуитивно и просто. Другие примеры генерирования JSON можно посмотреть на офсайте.

Парсинг JSON


А вот с парсингом дела обстоят намного хуже. Шутка:)



String json = "{paramsArray: [\"first\", 100],"
            + "paramsObj: {one: \"two\", three: \"four\"},"
            + "paramsStr: \"some string\"}";

JSONParser parser = new JSONParser();

Object obj = parser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
System.out.println(jsonObj.get("paramsStr"));
// some string

JsonObject jo = jsonObj.get("paramsObj");
System.out.println(jo.get("three"));
// four

JsonArray ja = jsonObj.get("paramsArray");
System.out.println(ja.get(1));
// 100

Вот такая отличная библиотека. Приятной работы!

47 комментариев:

  1. Этот комментарий был удален автором.

    ОтветитьУдалить
  2. Здравствуйте!
    Спасибо за статью, всё просто и понятно!
    Вот только ошибка возникает при запуске:

    No source code is available for type org.json.simple.JSONObject; did you forget to inherit a required module?

    Скажите, пожалуйста, чем она может быть обусловлена?
    (org.json.simple.JSONObject; импортирован, путь к .jar архиву прописан в classpath)

    ОтветитьУдалить
  3. Здравствуйте!

    Спасибо за комментарий.

    Я сейчас работаю в JDeveloper от Oracle, там свой процесс подключения jar'ников к проекту. IDE сама где-то прописывает их и копирует в проект. Думаю, аналогичные механизмы присутствуют в Eclipse и Netbeans.

    ОтветитьУдалить
  4. В последнем примере ошибка в самом начале:
    String json = "{paramsArray: [\"first\", 100],"
    + "paramsObj: {one: \"two\", three: \"four\"},"
    + "paramsStr: \"some string\"}";

    JSONParser parser = new JSONParser();

    Object obj = parser.parse(json);
    Переменной jsonString не было объявлено.

    ОтветитьУдалить
  5. Алексей Голобурдин, JsonObject jo и JsonArray ja. разве JSON не с большой буквы надо писать?

    Спасибо за статью=). Очень помог разобраться=)

    ОтветитьУдалить
  6. Работать с Форматом JSON, придется и на стороне сервера, так что всем кому интересно советую прочесть этот материал:

    Как работать с форматом JSON на PHP

    ОтветитьУдалить
  7. Безбожно ругается на этот код:
    "Unexpected character (p) at position 1.
    at org.json.simple.parser.Yylex.yylex(Yylex.java:610)
    at org.json.simple.parser.JSONParser.nextToken(JSONParser.java:269)
    at org.json.simple.parser.JSONParser.parse(JSONParser.java:118)
    at org.json.simple.parser.JSONParser.parse(JSONParser.java:81)
    at org.json.simple.parser.JSONParser.parse(JSONParser.java:75)".

    ОтветитьУдалить
  8. Такой код рабочий:

    String json = "{\"paramsArray\": [\"first\", 100], "
    + "\"paramsObj\": {\"one\": \"two\", \"three\": \"four\"}, "
    + "\"paramsStr\": \"some string\"}";

    JSONParser parser = new JSONParser();

    Object obj = parser.parse(json);
    JSONObject jsonObj = (JSONObject) obj;
    System.out.println(jsonObj.get("paramsStr"));
    // some string

    JSONObject jo = (JSONObject) jsonObj.get("paramsObj");
    System.out.println(jo.get("three"));
    // four

    JSONArray ja = (JSONArray) jsonObj.get("paramsArray");
    System.out.println(ja.get(1));
    // 100

    ОтветитьУдалить
  9. Подчеркивает строку - parser.parse(json);
    Какая у Вас версия json-simple?
    У меня - json-simple-1.1.1

    ОтветитьУдалить
    Ответы
    1. То же самое. Подскажите, как исправить?

      Удалить
  10. я javы маму ебал

    ОтветитьУдалить
    Ответы
    1. Фу гадость какая! Из за таких вот асоциальных элементов хочется мочить жалких людишек направо и налево.

      Удалить
    2. а я его папу и сестру! Пидарская java! элементарно распарсить ебаный json это целый пиздец! нахуя эти пидары не могли сделать 1 ебаную функцию parseFuckingJson(fuckingJson); вместо того чтобы создавать миллион библиотек!

      Удалить
    3. Для этого создали не функцию (и даже не метод) а целую кучу функциональных языков.
      Бысторо пишется - медленно исполняется.

      Удалить
    4. Анонимный2 июля 2013 г., 23:58

      Ежики плакали, кололись...

      Удалить
    5. Анонимный5 июля 2013 г., 13:13

      Кому Java не по душе могут идти по известному адресу и писать на том языке, на котором хочет. А я и дальше буду писать на "Пидорской" Java и зарабатывать в четыре раза больше, чем с++ кодер, решая те же задачи.

      Удалить
    6. К слову об одной функции.. ИМХО gson больше всего похож на самую простую библиотеку.

      Удалить
    7. Анонимный2 июля 2014 г., 14:36

      Бля пиздец вы тут развели... Java, плюсы... Оба языка хороши под свои нужды... Попробуй напиши на плюсах сервлет, а на java нативный драйвер шины PCI к примеру хотя бы... Если с первым справишься, со вторым Х*Й когда...

      Удалить
    8. Анонимный6 мая 2016 г., 13:28

      Каждый язык предназначен для решения определённого круга задач. На асме тоже можно написать сервлет, но это будет очень долго и не рентабельно. На C# тоже не напишешь нативный драйвер, например. Богатый выбор библиотек Java позволяет быстро решать задачи используя уже реализованный функционал, а не изобретать велосипед каждый раз. Больше библиотек хороших и разных!

      Удалить
  11. public class Settings {

    private static Settings _instance = null;
    private JSONObject cfg = null;
    private String fileName = "config.cfg";

    private Settings() throws Exception {

    Path p = Paths.get(fileName);
    if (Files.exists(p, LinkOption.NOFOLLOW_LINKS)) {

    JSONParser parser = new JSONParser();
    Object obj = parser.parse(new FileReader(fileName));
    cfg = (JSONObject) obj;

    } else {
    CreateDefaultCfgFile();
    System.out.println("File \"Config.cfg\" was created");
    System.exit(0);
    }
    }

    public synchronized ArrayList getPort() throws Exception {

    JSONArray ja = (JSONArray) cfg.get("port");
    ArrayList data = new ArrayList<>();
    for (int i = 0; i < ja.size(); i++) {
    data.add(ja.get(i).toString());
    }
    return data;
    }

    private void CreateDefaultCfgFile() throws Exception {
    JSONObject json = new JSONObject();
    JSONArray port = new JSONArray();
    port.add("COM9");
    port.add("/dev/ttyUSB0");
    json.put("port", port);

    String s = json.toJSONString();
    try (FileWriter f = new FileWriter(fileName, false)) {
    f.write(s);
    }
    }

    public synchronized static Settings getInstance() throws Exception {
    if (_instance == null) {
    _instance = new Settings();
    }
    return _instance;
    }
    }

    Так то получше будет. Что то у вас код в примере не очень супер..

    ОтветитьУдалить
  12. Хорошее изложение темы

    ОтветитьУдалить
  13. Автор дебил, вот что я хочу сказать.

    ОтветитьУдалить
  14. Анонимный27 мая 2014 г., 21:51

    Обажаю явку) Плюсики просто сосут со своей сложностью и синтаксисом позапрошлого века, шарп - нах, ибо микрософт, питон для фанатов, ну пхп и так понятно.. Разобраться, так и альтернативы достойной Яве просто нету.

    ОтветитьУдалить
    Ответы
    1. Анонимный15 июля 2014 г., 23:24

      Вот прям от души написано, друг мой, поддерживаю!!!)))))

      Удалить
    2. О, да! Графоманство в Яве зашкаливает. Сравнивать с Delphi, например, вообще не приходится. Жаль, нынче Делфи уже не используется, а в 90-х от Явы плевались.

      Удалить
    3. Анонимный19 июня 2015 г., 3:23

      А ещё раньше плевались когда девушки в штанах ходить начали.
      Это я к тому что все меняется и развивается

      Удалить
  15. Анонимный3 июня 2014 г., 17:53

    Спасибо за статью

    ОтветитьУдалить
  16. Анонимный6 июня 2014 г., 16:25

    > так и альтернативы достойной Яве просто нету.
    Вот это поворот! Невыносимо избыточной яве нет альтернатив. Ну, как говорится, кому и кобыла - невеста.

    ОтветитьУдалить
  17. Огромное спасибо автору за эту статью! =) Изучаю java всего второй день, ради экстренного написания программ с xml, json и protobuf, и настолько понятная статья - как раз то, что мне нужно хд Гран мерси.

    ОтветитьУдалить
    Ответы
    1. Отлично, рад, что помогло! Для второго дня Java - то, что нужно:)

      Удалить
  18. Привет!

    пример взял Ваш, самый первый, но почему-то ява выдаёт ворнинг следующего вида:
    RTT.java:309: warning: [unchecked] unchecked call to put(K,V) as a member of the raw type HashMap
    resultJson.put("num",new Integer(100));

    и таких 4. Есть какие-то идеи? гуглинг не помог.

    ОтветитьУдалить
  19. ПИШУ НА ПХП И Я ЛОЖИЛ ХУЙ НА ВАШУ ДЖАВУ

    ОтветитьУдалить
    Ответы
    1. Ну и напиши же *.apk на пхп...

      Удалить
    2. Ну и забей отверткой миллион гвоздей. Пыха не для этого создана, чтобы генерить apk файлы. А для написания веб приложения по мне на пыхе удобнее писать

      Удалить
  20. Замечательно, а как с помощью симпла распарсить вот такую вот нотацию JSONа:

    "university":
    {
    "students":
    {
    "petrovmb":
    {
    "name": ["petrov", "micael", "borisovich"],
    "telephones": ["1381", "1685"]
    }
    },
    }

    Т.е., по сути, структуру с тремя степенями вложенности, с учетом, что программе нужен доступ к каждому уровню непосредственно: к примеру, нужно обратиться к имени первого и второго уровня для решения каких-то задач.

    ОтветитьУдалить
  21. Анонимный14 июля 2015 г., 15:07

    Спасибо за статью

    ОтветитьУдалить
  22. Автор настолько крутой, что поддерживает свою крутость использованием сторонних библиотек

    ОтветитьУдалить
  23. вроде подключил все правильно саму библиотеку json-simple
    (import org.json.simple.JSONObject;)
    но ругается на
    JSONParser parser = new JSONParser();

    грит не занет такого класса !!!

    ОтветитьУдалить
  24. Object obj = parser.parse(json);
    parse - не видит, пишет "cannot resolve method..."
    что делать, помогите пожалуйста

    ОтветитьУдалить