Бесшумная обработка JSON с помощью Scala - PullRequest
15 голосов
/ 01 ноября 2010

Я из дотнет-земли, но недавно изучал возможности альтернативных языков программирования. Ничего серьезного, только кое-что здесь и там. Недавно я обнаружил Scala, и я очень очарован этим. Несмотря на недетерминированные манипуляции, я сделал несколько промежуточных проверок вещей, которые важны для меня в C #, и я чувствую себя довольно удовлетворенным: функциональные понятия - тик, специальный полиморфизм - тик, аннотации - тик, отражение и кодоген - тик.

Теперь я думаю о том, как можно запрограммировать аналог библиотеки обработки JSON, которую я реализовал в C # 4.0, с помощью DLR и «динамического» синтаксического сахара. Вот набор функций, которые я ищу:

  1. Удобный просмотр и построение необработанного JSON.
  2. Автоматическое преобразование между JSON и нативными объектами / коллекциями (в общем виде проблема неразрешима, хотя можно определить соглашения, которые будут работать 95% времени - и это хорошо для меня).

Новые возможности C # 4.0 вроде как здесь, так как они позволяют мне переопределять доступ к элементам и приведение типов для выполнения полностью настраиваемой логики (если переменная в C # 4.0 напечатана как «динамическая», то все, что вы с ней делаете, будет скомпилировано в вызовы определенных программистом методов с разумным поведением по умолчанию - см. методы DynamicMetaObject.BindXXX в MSDN для получения дополнительной информации). Например. Я переопределил приведение типов для сериализации / десериализации объектов .NET и доступа к членам для управления необработанным JSON, так что я могу написать следующий код:

var json = Json.Get("http://some.service");
if (json.foo) Console.WriteLine((Foo)json.foo);
json.bars = ((List<Bar>)json.bars).DoSomething();

Конечно, это не идеально, поскольку динамическое связывание в C # 4.0 имеет проблемы с методами расширения и выводом типов, и, кроме того, код все еще выглядит довольно тяжелым. Но в любом случае, это намного лучше, чем использовать все те ((JsonObject) json ["quux"]) ["baz"], которые я использовал в c # 3.5.

Некоторые фундаментальные исследования показывают, что в Scala нет специальных языковых функций, поддерживающих позднюю привязку. Тем не менее, существует так много хитростей, что, возможно, их можно использовать вместе, чтобы создать переносимую эмуляцию кода, показанного выше (или даже лучше - я почти уверен, что это возможно). Не могли бы вы посоветовать мне что-нибудь здесь?

Ответы [ 6 ]

15 голосов
/ 01 ноября 2010

Полезной библиотекой JSON для Scala является lift-json, который является автономным компонентом Lift Web Framework.

https://github.com/lift/framework/tree/master/core/json

Он поддерживает извлечение в классы, анализ и DSLдля создания JSON.

На странице, на которую я ссылаюсь, есть всеобъемлющее руководство, поэтому я не буду просто копировать и вставлять его.

6 голосов
/ 01 ноября 2010

Вы обязательно должны взглянуть на sjson.Здесь -> sjson на github Я использую реализацию на основе класса Type, которую вы можете просмотреть здесь -> некоторые примеры Если у вас есть прогон кода, есть некоторые действительно интересныеСкала трюки.Это должно дать вам то, что вы ищете в отношении # 2.SJSON упаковывает dispatch-json, который, как мне кажется, обеспечивает интеграцию с lift-json (упоминалось выше).Оба dispatch-json / lift-json должны дать вам то, что вы ищете в # 1.Для чего я стою, я использую sjson в большом проекте, и он идет гладко.И джентльмен, стоящий за проектом, был довольно удивительным и очень хорошо поддерживает проект.

5 голосов
/ 17 мая 2012

Я плавал между использованием lift-json и различными вариантами sjson (например, dabasishg / sjson ) и совсем недавно Jerkson ( Оболочка Scala на Джексон ).

В целях сериализации и десериализации объектов я продолжаю находить Jerkson, требующий наименьших настроек для выполнения работы, например, я только что кодировал простую сериализацию объектов с case class, которая выглядит как это:

import org.joda.time.LocalDate

case class UserStatus(subscriptionEndDate: LocalDate = null)

У меня были различные ошибки как с lift-json, так и с sjson, но jerkson только что работал с:

import com.codahale.jerkson.Json

val jsonString = Json.generate(statusObject)

и

val newObject = Json.parse[UserStatus](jsonString)
2 голосов
/ 02 ноября 2010

Как уже отмечали другие, есть много вариантов.Помимо упомянутых, большинство библиотек обработки Java JSON также должны работать с Scala, с различными уровнями (не) удобства для языков, не являющихся Java JVM (таких как Scala, Clojure, Groovy).

Наиболее мощныес точки зрения связывания данных Джексон , GSON и FlexJSON .Одна из возможностей - проверить их и посмотреть, сможете ли вы улучшить совместимость - например, в Scala есть ряд «экзотических» типов данных, которые выиграют от явной обработки (помимо обработки «стандартных» объектов Java, которые поддерживают библиотеки libs).).

1 голос
/ 17 декабря 2011

Если вы хотите что-то действительно динамичное в scala, вот оно: http://www.scala -lang.org / api / current / scala / Dynamic.html

A marker trait that enables dynamic invocations. Instances x of this trait allow calls x.meth(args) for arbitrary method names meth and argument lists args. If a call is not natively supported by x, it is rewritten to x.applyDynamic("meth", args).

As of scala 2.9, scalac must receive the -Xexperimental optional for Dynamic to receive this treatment.

СейчасЭто экспериментальная функция, и она не так сильна, как .NET DLR.

Casbah драйвер scala-mongodb его пробовал.

0 голосов
/ 08 ноября 2012

Интересно, что код, выполняющий это в scala, НАМНОГО более сложный, чем Java. Ни один из этих ответов не дает бесшумного решения, такого как библиотека Java Jackson, за исключением Jerkson, который охватывает Джексона.

ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally User user = mapper.readValue(new File("user.json"), User.class); //to parse mapper.writeValue(new File("user-modified.json"), user); //to produce

...