проверка JSON в Скала с Лифт-JSON - PullRequest
4 голосов
/ 28 февраля 2012

Я хотел бы проверить, что json содержит список ключей / значений, прежде чем пытаться маршалировать в класс case с использованием lift-json.Данные могут быть вложенными.

Например:

{ 
 "name": "stack",
 "desc": "desc",
 "age": 29,
 "address": {
  "street": "123 elm", 
  "postal_code": 22222,
  "city": "slc",
 }
}

Как можно проверить, что этот JSON содержит значения для "name", "age" и "address \ street"?Предположим, что все остальные поля являются необязательными.

Извините, если я упустил что-то очевидное, но я подозреваю, что что-то подобное уже было решено ранее.

Кстати, кто-нибудь пробовал Orderly?https://github.com/nparry/orderly4jvm

Ответы [ 5 ]

4 голосов
/ 28 февраля 2012

На мой взгляд, у вас есть несколько вариантов:

  1. Вы могли бы использовать "API низкоуровневого парсера" от lift-json (найдите эту фразу на этой странице ), чтобы получить все поля, которые вас интересуют. Если вы не получили все нужные поля в тот момент, когда встречаете токен End, вы выбрасываете исключение. Если у вас есть обязательное поле, создайте свой объект.

    Pro : JSON анализируется только один раз. Это самый эффективный способ использования lift-json.

    Con : Вы создали хрупкое программное обеспечение, свернутое вручную.

  2. Вы можете использовать JsonAST от lift-json, который является нормальным результатом вызова его метода parse (поиск "Parsing JSON" на этой странице ), а затем его XPath-подобный выражения (ищите «XPath + HOFs» на этой странице ), чтобы определить наличие обязательных полей. Если это так, создайте свой объект, передав соответствующие поля конструктору.

    Pro : меньше рук, чем # 1. Анализирует данные только один раз.

    Con : Это не так быстро, как # 2.

  3. Используйте методы из # 1 или # 2, чтобы определить наличие обязательных полей. Если это так, используйте десериализацию lift-json (посмотрите заголовок «Сериализация» на эта страница ), чтобы создать объект и создать объект.

    Pro : Я действительно растягиваюсь здесь ... Если вы ожидаете, что большая часть данных будет плохой, вы сможете определить это, прежде чем вводить несколько более тяжеловесный процесс десериализации лифта-JSON

    Con : Вы проанализировали данные дважды, если они действительны.

  4. Просто используйте десериализацию lift-json (ищите заголовок «Сериализация» на на этой странице ). Он более или менее выполняет то, что описано в # 2, за исключением того, что использует отражение, чтобы выяснить, какие поля являются обязательными.

    Pro : это наиболее удобное решение

    Con : Это медленнее, чем # 1 и # 2.

Моя рекомендация: Если вам абсолютно не нужна максимальная производительность, используйте # 4. Если вам действительно нужна скорость, используйте # 1. Еще одно преимущество использования решения в стиле № 1 или № 2 заключается в том, что они позволяют вам выполнять странные приведения к данным, такие как сопоставление двух альтернативных имен полей в JSON с одним полем в объекте scala.

0 голосов
/ 12 декабря 2014

Наша команда начала присматриваться к Ордену.Для объектов JSON, которые мы используем, OrderLy может достаточно описать их.Я думаю, что мы будем их использовать.

Упорядоченная библиотека, о которой вы упомянули: https://github.com/nparry/orderly4jvm, кажется очень хорошей.Он выдает приличные сообщения об ошибках при сбое проверки.

Мы рассмотрели использование схемы Json, в частности json-schema-validator библиотеки Java: https://github.com/fge/json-schema-validator

Сообщения об ошибках не были такими описательными.

0 голосов
/ 18 мая 2013

Я разработал этот анализатор / валидатор json https://github.com/HigherState/jameson

0 голосов
/ 10 августа 2012

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

0 голосов
/ 28 февраля 2012

Это сработало для меня: JSON в XML в Scala и работа с параметром Option ()

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

import util.parsing.json.JSON._

object JsonSoap {
  def main(args: Array[String]) {
    val x = parseFull("""{"name":"Joe","surname":"SOAP"}""")

    val y = x collect {
      case m: Map[_, _] => m collect {
        case (key: String, value: String) => key -> value
      }
    }

    val z = for (m <- y; name <- m.get("name"); surname <- m.get("surname"))
    yield {
      <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
        <soap:Body>
          <Person>
            <Name>{name}</Name>
            <Surname>{surname}</Surname>
          </Person>
        </soap:Body>
      </soap:Envelope>
    }

    println(z)
  }
}

Вы уже рассматривали следующие вопросы:

Разбор JSON в Scala с использованием стандартного Scala

Анализ JSON и итерация по объекту

Простой JSON в XML

...