четверг, 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

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

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

  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. Ответы
    1. Фу гадость какая! Из за таких вот асоциальных элементов хочется мочить жалких людишек направо и налево.

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

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

      Удалить
    4. Ежики плакали, кололись...

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

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

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

      Удалить
    8. Каждый язык предназначен для решения определённого круга задач. На асме тоже можно написать сервлет, но это будет очень долго и не рентабельно. На 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. Обажаю явку) Плюсики просто сосут со своей сложностью и синтаксисом позапрошлого века, шарп - нах, ибо микрософт, питон для фанатов, ну пхп и так понятно.. Разобраться, так и альтернативы достойной Яве просто нету.

    ОтветитьУдалить
    Ответы
    1. Вот прям от души написано, друг мой, поддерживаю!!!)))))

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

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

      Удалить
  15. Спасибо за статью

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

    ОтветитьУдалить
  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. Спасибо за статью

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

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

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

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

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