Html to json android

html2json

Как обычно мы храним в базе данных что-то, что нужно показать пользователю и обладает некоторыми свойствами разметки? Кто хотя бы раз делал свой блог, хабр или похожее сразу скажет — html. А что, если я скажу, что можно сделать иначе? JSON.

Я бы хотел рассмотреть преимущества и недостатки подобного хранения, ну или попытаться, по крайней мере.

Что? Json? Зачем это вообще надо?

Описание:

У нас имеется сервис, в бд мы храним html для отображения некоторого контента.

Если я не ошибаюсь, то так как раз сделано на всем нами любимом (или не сильно) хабре. \
(Я посмел предположить, что хабр хранит статьи именно так)

Проблема:

Мы, как фронтендеры, должны поддерживать на клиенте некоторый набор легаси css или как-то тяжело его обновлять.

Если наш фронтендер захочет как-то обновить наш UI, то он должен учитывать, что на сервере весь html в бд содержит старые классы css и волшебным образом не поменяется и скорее всего вообще меняться не будет.

Можно, например, посмотреть, что выдается для мобильной версии фронтенда хабра под недавним мегапостом ссылка на апи. Конечно, сомнительно, что пост хранится прям в таком виде в бд, но все может быть. (возможно, это связанно с тем что апи хабра до сих пор не открыто)

Внимание: Не большой скрин, просьба спрятать женщин, детей и слишком чувствительных гиков:

Некоторое количество заинлайненого css и javascript (около половины поста генерируется им) осталось за кадром.

Решение:

Будем хранить не html, а json, с определенной заранее или легко расширяемой структурой, что бы каждый элемент имел четкую структуру и был далек от представления у фронтендера.

Профит, который получим:

Мы полностью абстрагировались от представления данных и сконцентрировались лишь на содержимом. Благодаря этому мы в любой момент сможем с достаточной простотой обновить код преобразования (или рендер) json в отдаваемый браузеру html. Только теперь мы сможем написать похожий рендер из json’а не только в html, но и для нативных приложений без необходимости использовать Web View и аналоги.

Рассмотрим идею на примерах

Для этого предлагаю ознакомится с тем, что выдает по api Хабр (только уже без мегапостов) \
Важно: я предполагаю, что статьи хранятся в том же виде, в каком и отправляются.

Показывать я будут сначала html, а потом альтернативу в виде json.

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

Рассмотрим более комплексный пример.

А вот так может например выглядит спойлер (просто напомню, что в html5 давно есть details):

Иииии… преобразуем это в json:

Вообще, Html очень удобен, чтобы представлять просто текст.
Только взгляните на этого монстра:

Примечание: mode используется для того, чтобы представлять такие значения как bold , italic , strike и группировать их, просто пример не очень удачный.

Столько символов, чтобы представить один параграф с одной ссылкой.

Удобно ли это? Не уверен, легко можно выяснить какие стили у конкретного span без необходимости ходить для поиска предыдущих нод, но, например, в андроид есть стандартный TextView , который без проблем сработается с простеньким html

Все это я, конечно, переводил не в ручную (кроме некоторых кейсов). Я брал некоторые статьи и прогонял html через свою небольшую консольную утилиту на Dart, её результаты работы вы и увидели. Да, она написана не идеально, но для проверки концепта — сойдет.

Потыркать утилиту и посмотреть код можно по ссылке на мой репозиторий.

Вообще к чему эти примеры. Ими я хотел сказать, что если заставляете пользователей использовать html для создания статей, то результат становится непредсказуемым, а повлиять на него можно лишь большим усилием и при желании самого пользователя.

Небольшой бенчмарк

Что я вообще сравниваю? Мне интересно 2 вещи:

  1. Есть ли разница в скорости парсинга json с заинлайненым html и json с представлением статьи в виде json’а.
  2. Насколько быстро распарсить два формата вложенных друг в друга.
Читайте также:  Фокус андроида с картами

Зачем тестировать второй вариант? Если вы используете React, например, вместе с библиотекой «html_to_react» (внутри она использует «html-dom-parser»), то, думаю, вам будет интересно узнать об альтернативе.

Кратко опишу методику тестирования:

  • Я заранее перевел с помощью утилиты пару хабровских статей в json.
  • Есть три операции, которые, тестируются:
    1. Скорость парсинга статьи без преобразований (статья полностью в том виде в котором его выдает по апи хабр, в html)
    2. Скорость парсинга если html заменить на преобразованный моей утилитой json
    3. Скорость парсинга когда парсим сначала json а после парсим html внутри.
  • тестируем библиотеку только для построения dom дерева, замеры для «html_to_react» не проводились

Результаты тестирования

После запуска бенчмарка мы получим такие результаты:

  1. Скорость парсинга статьи полностью из json’а и с html внутри json’а по производительности не имеет значительной разницы.
  2. Производительность при двух проходах парсинга (сначала парсим json, а потом html) примерно в 2 раза меньше и не в пользу html.

Ок, а какие плюсы и минусы подобного решения?

Сделав подобное преобразование на сервере, в некоторых ситуациях можно немного ослабить нагрузку на гаджет пользователя

Независимость от html

Мы устраняем зависимость от того как хотим представлять на клиенте кнопку, спойлер, или цитату. независимы от css классов от различных атрибутов.

Мы получаем возможность безболезненно создать на основе данных с сервера нативные виджеты, будь то андроид, ios, flutter, web или что-то из мира десктопа.

И это все без WebView и аналогов.

Избавляемся от зависимостей

json весит незначительно, но больше чем аналогичный html

возможно и обратное, если:

  • у вас более сложная структура, которая лучше поддается оптимизации
  • вы захотите использовать бинарный формат для представления вашего json (забавно — bson оказался в моем случае даже больше чем стандартный json), тогда получится сократить размер, но опять же это достаточно трудоемко, а фичи не ждут.

json придется в любом случае конвертировать в нативные для данной платформы виджеты будь то веб с его html или нативный мир уже с собственными особенностями

И при этом не очень понятно, когда это лучше делать в случае веб-приложений:

  • Можно конвертировать прямо на клиенте, что удобно в случае, если вы используете кастомные виджеты.
  • Можно конвертировать на сервере, а на фронтенд отправлять уже все готовое.

html очень многогранный, и если есть необходимость поддерживать весь html, то, на мой взгляд, затея выглядит достаточно сомнительной и трудоемкой (не придешь ли ты случайно к тому, что изобретешь браузер)

отсутствует стандартизация, получается, что вы создаете велосипед и поддерживать его придется вам

Это все, конечно, хорошо, но как можно это применить?

Вот мой небольшой список:

  1. Создание платформо-независимого генерируемого в рантайме ui
  2. Отказ от редакторов, использующих html. Написать собственный редактор получится проще и, скорее всего, он будет безопаснее, т.к. встроить зловредный javascript будет сложнее.
  3. Думаю, можно продолжать дальше, но я больше ничего не смог придумать, надеюсь читатели помогут и предложат еще вариантов.

Заключение

В качестве итога я бы хотел сказать, что не предлагаю всем разом переходить на описанный мной в данной статье подход. В первую очередь мне интересно мнение других разработчиков, как бекенд, так и фронтенд. Скорее всего, я не учел нюансы и готов выслушать и обсудить критику и замечания.

Источник

JSON Parsing in Android

JSON (JavaScript Object Notation) is a straightforward data exchange format to interchange the server’s data, and it is a better alternative for XML. This is because JSON is a lightweight and structured language. Android supports all the JSON classes such as JSONStringer, JSONObject, JSONArray, and all other forms to parse the JSON data and fetch the required information by the program. JSON’s main advantage is that it is a language-independent, and the JSON object will contain data like a key/value pair. In general, JSON nodes will start with a square bracket ([) or with a curly bracket (<). The square and curly bracket’s primary difference is that the square bracket ([) represents the beginning of a JSONArray node. Whereas, the curly bracket ( <)represents a JSONObject. So one needs to call the appropriate method to get the data. Sometimes JSON data start with [. We then need to use the getJSONArray() method to get the data. Similarly, if it starts with <, then we need to use the getJSONobject() method. The syntax of the JSON file is as following:

Читайте также:  Как сделать фейк для андроид

In this article, we are going to parse a JSON file in Android. Note that we are going to implement this project using the Kotlin language.

Step by Step Implementation

To parse a JSON file in Android, follow the following steps:

Step 1: Create a New Project

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Kotlin as the programming language.

Источник

Android Studio: получение JSON в ListView с сервера на хостинге. Урок № 3

Всем привет и это уже третья статья и видео, посвященные работе в Android Studio с json файлами.

Из этой статьи вы узнаете как в android studio получать данные из JSON в ListView с сервера на хостинге.

Мы всё ближе и ближе подходим к тому, чтобы наконец-то начать получать данные с сервера на хостинге, а вот сейчас мы займемся как раз разбором данного примера.

Мы загрузим наш тестовый json файл с пользователями на хостинг и будем получать данные уже непосредственно из интернета.

Надеюсь видео вам понравится, можете пока создается новый проект поставить пальцы вверх, подписаться на канал, и мы приступаем.

Смотрите видео: Android Studio: получение JSON в ListView с сервера на хостинге. Урок № 3

Создаем новый проект, выбираем emptyActivity , традиционно жмем Next, назовём новый проект Load json from url -01 , финиш.

Пока подготавливается проект, хочу сказать, что я выложил наш тестовый json файл на хостинг и буду использовать его в качестве примера. Вы можете выложить свой файл, как Вам будет удобно с вашим содержимым. Замечу, что заходить по ftp на сервер, создавать домены, поддомены, создавать директории на хостинге вы обязаны уметь.

Если мы перейдём по ссылке m1.maxfad.ru/api/users.json, то мы можем увидеть структуру файла, перечень пользователей, электронные адреса. Сейчас это всё находится уже на хостинге в интернете.

Давайте поработаем над нашим проектом, кое-что будем использовать из второго урока, код будет немного совпадать, кто не смотрел предыдущие примеры, обязательно посмотрите.

Давайте сразу через New Resource File снова сделаем row.xml , для вывода пунктов нашего списка, чуть позже вернемся к нему.

Откроем AndroidManifest.xml , в нем нужно будет указать разрешение для работы с интернетом.

Также нам понадобится gradle файл, и в него мы вставим имплементацию библиотеки, которую Вы наверное, уже знаете, может кто-то уже слышал, это volley, по крайней мере так я её произношу.

Синхронизируем gradle , произошло добавление, будем работать с этой библиотекой, она как раз используется для сетевых запросов, для получения данных с сайтов и тому подобного.

В AndroidManifest добавим пользовательское разрешение для работы с интернетом.

Хочу сделать маленькое замечание, пока мы не начали всё писать, поскольку у меня, а возможно такое будет и у вас, сертификат не распространяется на поддомены, то для того чтобы не выдавались сообщения об ошибке, Вам нужно будет включить в блок application следующюю запись.

Это вроде как позволяет работать с недостоверными, скажем так с точки зрения Google, сайтами это требование корпорации добра, для вашей безопасности. С манифестом и с gradle закончили.

Теперь перейдем в activity_main , по традиции мы снова будем делать listview , заменим на RelativeLayout , textview меняем на listview , убираем отсюда опять всё ненужное.

Так значит для listview добавим android:id listView , ширина и высота — wrap_content .

Добавим еще один элемент для отображения сетевой активности, ProgressBar ширина wrap_content , высота тоже wrap_content .

Сделаем видимость ProgressBar в

Вот теперь важное: для ProgressBar добавить нужно центрирование по горизонтали и по вертикали, чтобы элемент был по центру экрана.

Так он пока где-то находится, его не видно, можно посмотреть. он находится по центру и будет крутиться.

Перейдём в row.xml для вывода пунктов, сделаем здесь LinearLayout , ширина match_parent , а высота wrap_content , ориентация вертикальная, отступы – 16dp .

Так теперь добавим два textview , вы уже знаете какие, это у нас будут для name и email.

Добавим для видимости текст,

Так значит нам нужно будет создать новый класс для обработки. Наш класс мы назовём ListViewAdapter .

И теперь я буду вставлять куски кода, потому как мы его писали в прошлый раз, но для тех, кто не смотрел, кое-что расскажу, буду уже всё равно блоками вставать, поскольку он практически готов.

Читайте также:  Нокия люмия 620 андроид или нет

Снова напишем конструктор, в котором будем вызываться контекст, слой, которые у нас row , будем вызывать поля, в принципе можно там первое вызвать name и уже будет работать и список который будет передавать данные.

Метод super это всё вызывает, здесь присвоение переменных.

Ну и опять без изменений практически из второго видео, с некоторыми оговорками получается вот такая функция.

В getView определяем слой для вывода данных, обращаемся к элементам пункта name , email . В блоке обработки исключений try/catch циклично присваиваем текст, получая его из списка userlist .

Кто смотрел мое второе видео по json , тот знает, что это такое, в принципе больше на этом останавливаться не будем.

Теперь переходим в mainactivity и поработаем в ней. Итак, нам нужно будет объявить несколько переменных, переменная JSON_URL в которой мы будем хранить наш адрес, по которому будет лежать наш файл на сайте.

и ListView listView для списка.

Я надеюсь вы знаете как заливать файлы на хостинг, поэтому я не буду рассказывать, как мне удалось создать папку api в поддомене и положить туда файл, думаю это вам уже известно, если вы занимаетесь и обучайтесь разработке Android приложений для себя, либо по учёбе, по работе.

Сразу же мы получаем наш listView , наш список через findViewById

А вот теперь мы напишем вот такую строчку,

это по сути в onCreate больше ничего не будет. Дальше будет несколько функций, которые мы напишем в рукопашную.

И эта функция loadJSONFromURL будет вызывать наш адрес, и будем получать данные.

Далее напишем ручками Private void loadJSONFromURL , в качестве параметра Stirling передаём url .

Нужно будет обратиться к нашему элементу ProgressBar , который у нас указан в activity_main progressBar

ProgressBar надо будет сделать видимым

Теперь пишем StringRequest , обратите внимание это мы работаем с библиотекой volley ,

передаём наш url , пишем new Response.Listener

Открываем скобки пишем @Override ,

Нам нужно добавить метод onResponse , подключить сюда onResponse .

Далее делаем ProgressBar не видимым.

Всё мы его скрыли, теперь у нас идёт обработчик исключений try , пишем

и указываем нашу таблицу users , которая у нас внутри файла users.json .

Объявляем ArrayList JSONObject

и вот здесь мы напишем ту функцию, которую мы писали в прошлый раз.

В прошлый раз, я хочу напомнить, мы её вставим вне функций, мы её Встаём целиком и полностью, можете скопировать её из второго примера. Поскольку будем выполнять то же самое действие здесь.

Не буду останавливаться, но тут происходит наполнение данными из массива. Передаём jsonArray , далее пишем ListAdapter adapter

И теперь для списка установим адаптер

Блок исключений catch

Далее идет Response.ErrorListener

В нем Toast выводит ошибки. Что такое тосты уже знаете, последние две строчки данной функции

Вот теперь только вызываться наша библиотека, которая в конце концов вызовет наконец-то запрос и сформирует нужный результат.

Так, здесь я пропустил запятую после переменной url , и в принципе больше у нас ни каких нюансов быть не должно… А они будут…)

Сохраняем, запускаем… Эмулятор запустился, и мы получили данные…

Поскольку наш файл вряд ли был в кодировке UTF-8 , но здесь должен быть четко UTF-8 . Напишу для себя UTF-8 , должна быть такая кодировка, тогда у нас будут русские буквы, русский текст нормально выглядить.

Сложно догадаться, что это Коля, Вася, Федя, и тому подобное, хотя email отобразился нормально.

Значит нам нужно будет написать ещё одну небольшую функция, которая превратит наш ответ – response , превратит эту кашу в кодировку UTF-8 .

Итак давайте исправим это недоразумение, написав еще одну функцию EncodingToUTF8

В качестве параметра передаём string response , сразу try обработчик, пишем массив байт, code

Ответ в строку, получим байты в кодировке ISO-8859-1 , западноевропейская кодировка, и конвертируем в UTF-8 , перегоним нашу абракадабру в понятный вид.

После обработки ошибок Catch вернем строковое значение response.

Вот такая получилась небольшая функция в принципе когда мы перейдём наконец-то в четвёртый урок, в четвёртом занятие, мы будем получать данные уже непосредственно из PHP с базы данных на хостинге, и этот костыль не понадобится, поскольку мы обойдемся без неё, там уже будем конвертировать текст, можно в базе указать.

И давайте её вызовем EncodingToUTF8 наш response , сохраним и перезапустим.

Вот так, всего лишь одна небольшая функция и мы превратили абракадабру во вполне понятной вид.

Источник

Оцените статью