使用 Scala 进行无噪声 JSON 处理

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4065897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:32:26  来源:igfitidea点击:

Noise-free JSON processing with Scala

jsonscaladsl

提问by Eugene Burmako

I'm coming from a dotnet land, but recently have been looking at the possibilities of alternative programming languages. Nothing really serious, just some bits here and there. Recently I've discovered Scala and I'm pretty fascinated with it. Despite non-deterministic tinkering, I've done some intermediate checks of stuff that is important for me in C# and I feel rather satisfied: functional notions - tick, ad-hoc polymorphism - tick, annotations - tick, reflection and codegen - tick.

我来自 dotnet 领域,但最近一直在寻找替代编程语言的可能性。没什么特别严重的,只是这里和那里的一些东西。最近我发现了 Scala,我对它非常着迷。尽管进行了非确定性修补,但我已经对 C# 中对我很重要的东西进行了一些中间检查,我感到相当满意:功能概念 - 刻度线、临时多态性 - 刻度线、注释 - 刻度线、反射和代码生成 - 刻度线。

Now I'm thinking about how one would program an analogue of JSON processing library I've implemented in C# 4.0 with the help of DLR and "dynamic" syntactic sugar. Here's the feature set I'm looking for:

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

  1. Convenient browsing and construction of raw JSON.
  2. Automatic conversion between JSON and native objects/collections (in its general form the problem is unsolvable, though one can define conventions that will work 95% of the time - and that's fine for me).
  1. 方便浏览和构建原始 JSON。
  2. JSON 和本机对象/集合之间的自动转换(就其一般形式而言,该问题无法解决,尽管可以定义在 95% 的情况下都有效的约定——这对我来说很好)。

New features of C# 4.0 kinda rock here, since they let me override member access and type casts to perform completely custom logic (if a variable in C# 4.0 is typed as "dynamic", then anything you do with it will be compiled into calls to programmer-defined methods with reasonable default behaviour - see DynamicMetaObject.BindXXX methods at MSDNfor more info). E.g. I've overriden type casts to serialize/deserialize .NET objects and member accesses to manage raw JSON, so that I can write the following code:

C# 4.0 的新特性在这里有点摇滚,因为它们让我覆盖成员访问和类型转换来执行完全自定义的逻辑(如果 C# 4.0 中的变量被键入为“动态”,那么你对它所做的任何事情都将被编译成对具有合理默认行为的程序员定义的方法 -有关详细信息,请参阅MSDN 上的 DynamicMetaObject.BindXXX 方法)。例如,我覆盖了类型转换以序列化/反序列化 .NET 对象和成员访问以管理原始 JSON,以便我可以编写以下代码:

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

Of course, this is not ideal, since dynamic binding in C# 4.0 has problems with extension methods and type inference, and, moreover, the code still feels rather heavyweight. But anyways, this is much better than using all those ((JsonObject)json["quux"])["baz"] I've used to in c# 3.5.

当然,这并不理想,因为 C# 4.0 中的动态绑定在扩展方法和类型推断方面存在问题,而且代码仍然感觉比较重量级。但无论如何,这比在 c# 3.5 中使用的所有 ((JsonObject)json["quux"])["baz"] 好得多。

Some basic research shows that Scala doesn't have dedicated language features that support late binding. However, there are so many tricks that maybe they can be used together to create a bearable emulation of the code shown above (or even to be better - I almost sure that this is possible). Could you, please, advise me something here?

一些基础研究表明 Scala 没有支持后期绑定的专用语言特性。然而,有很多技巧,也许它们可以一起使用来创建上面显示的代码的可忍受的模拟(或者甚至更好 - 我几乎可以肯定这是可能的)。你能在这里给我一些建议吗?

回答by tylerweir

A useful JSON library for Scala is lift-json, which is a standalone component of the Lift Web Framework.

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

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

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

It supports extraction to classes, parsing and a DSL for creating JSON.

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

The page I linked to has a comprehensive tutorial, so I won't just copy and paste it.

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

回答by Vonn

You should definitely have a look at sjson. Here -> sjson on githubI'm using the Type class based implementation, which you can peruse here -> some examplesIf you have a jaunt through the code, there's some really interesting scala tricks. This should give you what you're looking for in regards to #2. SJSON wraps dispatch-json which I believe provides integration to lift-json(mentioned above). Both dispatch-json/lift-json should give you what you're looking for in #1. For what its worth I've been using sjson in a large project and its going swimmingly. And the gentleman behind the project has been pretty amazing and supports the project very well.

你绝对应该看看 sjson。此处 -> github 上的 sjson我正在使用基于 Type 类的实现,您可以在此处仔细阅读 ->一些示例如果您对代码进行了一次短途旅行,那么这里有一些非常有趣的 scala 技巧。这应该给你你正在寻找的关于#2 的东西。SJSON 包装了 dispatch-json,我相信它提供了与lift-json(上面提到的)的集成。dispatch-json/lift-json 都应该给你你在 #1 中寻找的东西。就其价值而言,我一直在一个大型项目中使用 sjson 并且进展顺利。项目背后的绅士非常了不起,并且非常支持该项目。

回答by sroebuck

I've floated between using lift-jsonand various variants of sjson(e.g. dabasishg/sjson) and more recently Jerkson(a Scala wrapper on Hymanson).

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

For the purposes of object serialization and deserialization I keep on finding Jerksonto require the least tweaking to get a job done, for example, I've just been coding a simple object serialisation with a case classthat looks like this:

出于对象序列化和反序列化的目的,我一直发现Jerkson需要最少的调整才能完成工作,例如,我刚刚编写了一个简单的对象序列化代码case class,如下所示:

import org.joda.time.LocalDate

case class UserStatus(subscriptionEndDate: LocalDate = null)

I had various errors with both lift-jsonand sjsonbut jerksonjust worked with:

我有两个各种错误lift-jsonsjson,但jerkson只是工作:

import com.codahale.jerkson.Json

val jsonString = Json.generate(statusObject)

and

val newObject = Json.parse[UserStatus](jsonString)

回答by StaxMan

As others have pointed out, there are many choices. Beyond ones mentioned, most Java JSON processing libraries should work with Scala, too, with varying levels of (in)convenience for non-Java JVM languages (like Scala, Clojure, Groovy).

正如其他人指出的那样,有很多选择。除了提到的之外,大多数 Java JSON 处理库也应该与 Scala 一起使用,对于非 Java JVM 语言(如 Scala、Clojure、Groovy)具有不同程度的(不)便利性。

Ones that are most powerful in terms of data binding are Hymanson, GSONand FlexJSON. One possibility is to check them out, and see if you can help improve interoperability -- Scala for example has a number of "exotic" data types that would benefit from explicit handling (above and beyond handling of 'standard' java objects that libs support).

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

回答by iron9light

If you wanna some thing really dynamic in scala, here it is: http://www.scala-lang.org/api/current/scala/Dynamic.html

如果你想要在 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.

Now, it's a experimental feature, and not as strong as the .NET DLR.

现在,它是一项实验性功能,不如 .NET DLR 强大。

Casbahthe scala-mongodb-driver has tried it.

Casbahscala-mongodb-driver 已经尝试过了。

回答by Ryan Medlin

interestinly enough the code to do this in scala is WAY more involved than that of Java.. none of those answers give a noise free solution like the Java Hymanson library except for Jerkson which wraps around Hymanson.

有趣的是,在 Scala 中执行此操作的代码比 Java 的代码要复杂得多。这些答案都没有提供像 Java Hymanson 库这样的无噪音解决方案,除了围绕 Hymanson 的 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

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