使用Scala进行无噪声JSON处理

时间:2010-11-01 00:15:19

标签: json scala dsl

我来自dotnet的土地,但最近一直在研究替代编程语言的可能性。没有什么比这更重要的了,只是在这里和那里。最近我发现了Scala,我非常着迷它。尽管有非确定性的修补,但我已经对C#中的一些重要事项进行了一些中间检查,我感到相当满意:功能概念 - tick,ad-hoc多态 - tick,注释 - tick,reflection和codegen - tick。

现在我正在考虑如何在DLR和“动态”语法糖的帮助下编写我在C#4.0中实现的JSON处理库的模拟。这是我正在寻找的功能集:

  1. 方便地浏览和构建原始JSON。
  2. JSON和本机对象/集合之间的自动转换(在一般形式中,问题是无法解决的,尽管可以定义95%的时间可以工作的约定 - 这对我来说很好)。
  3. C#4.0的新功能在这里有点摇滚,因为它们让我覆盖成员访问和类型转换以执行完全自定义逻辑(如果C#4.0中的变量被输入为“动态”,那么你用它做的任何事情都将被编译调用具有合理默认行为的程序员定义的方法 - 有关详细信息,请参阅DynamicMetaObject.BindXXX methods at 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 个答案:

答案 0 :(得分:15)

Scala的一个有用的JSON库是lift-json,它是Lift Web Framework的独立组件。

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

它支持提取类,解析和用于创建JSON的DSL。

我链接的页面有一个全面的教程,所以我不会只复制并粘贴它。

答案 1 :(得分:6)

你一定要看看sjson。这里 - &gt; sjson on github 我正在使用基于Type类的实现,您可以在这里仔细阅读 - &gt; some examples 如果你在代码中有一个短途旅行,那么有一些非常有趣的scala技巧。这应该会给你关于#2的所需信息。 SJSON包装dispatch-json,我认为它提供了与lift-json的集成(如上所述)。 dispatch-json / lift-json都应该为你提供你在#1中寻找的东西。为了它的价值我一直在一个大型项目中使用sjson并且它正在游泳。这个项目背后的绅士非常了不起,并且很好地支持了这个项目。

答案 2 :(得分:5)

我在使用lift-jsonsjson的各种变体(例如dabasishg/sjson)和最近JerksonJackson上的Scala包装器)之间徘徊

出于对象序列化和反序列化的目的,我继续寻找Jerkson以完成最少的调整以完成工作,例如,我刚刚使用{{1}编写了一个简单的对象序列化看起来像这样:

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)

答案 3 :(得分:2)

正如其他人所指出的,有很多选择。除了提到的,大多数Java JSON处理库也应该与Scala一起使用,为非Java JVM语言(如Scala,Clojure,Groovy)提供不同级别的(in)方便。

在数据绑定方面最强大的是JacksonGSONFlexJSON。一种可能性是检查它们,看看你是否可以帮助提高互操作性 - 例如Scala有许多“异国情调”的数据类型,它们将受益于显式处理(超出libs支持的'标准'java对象的处理)。

答案 4 :(得分:1)

如果你想在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-driver已经尝试过了。

答案 5 :(得分:0)

有趣的是,在scala中执行此操作的代码比Java的代码要多得多。这些答案都没有提供像Java Jackson库这样的无噪声解决方案,除了Jerkson包围Jackson。

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