2010-11-01 16 views
15

Vengo de un país de dotnet, pero recientemente he estado estudiando las posibilidades de los lenguajes de programación alternativos. Nada realmente serio, solo algunas partes aquí y allá. Recientemente descubrí a Scala y estoy fascinado con eso. A pesar de retoques no deterministas, he hecho algunas comprobaciones intermedias de cosas que son importantes para mí en C# y me siento bastante satisfecho: nociones funcionales - tic, polimorfismo ad-hoc - tic, anotaciones - tic, reflexión y codegen - tic.Procesamiento JSON sin ruido con Scala

Ahora estoy pensando en cómo se podría programar un análogo de la biblioteca de procesamiento JSON que he implementado en C# 4.0 con la ayuda de DLR y azúcar sintáctica "dinámica". Aquí está el conjunto de características que estoy buscando:

  1. Navegación conveniente y construcción de raw JSON.
  2. Conversión automática entre JSON y objetos/colecciones nativas (en su forma general, el problema es insoluble, aunque se pueden definir convenciones que funcionarán el 95% del tiempo, y eso está bien para mí).

nuevas características de C# 4.0 un poco de rock aquí, ya que me dejaron de anulación del acceso de miembros y el tipo de moldes para ejecutar una lógica completamente personalizado (si es una variable en C# 4.0 se escribe como "dinámica", entonces cualquier cosa que hagas con ella se compilará en llamadas a métodos definidos por el programador con un comportamiento por defecto razonable - ver DynamicMetaObject.BindXXX methods at MSDN para más información). P.ej. Tengo tipo overriden proyecta para serializar objetos/deserializar .NET y miembro de accesos para manejar JSON prima, de modo que pueda escribir el siguiente código:

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

Por supuesto, esto no es ideal, ya que la unión dinámica en C# 4.0 tiene problemas con los métodos de extensión y la inferencia tipo, y, además, el código todavía se siente bastante pesado. Pero de todos modos, esto es mucho mejor que usar todos esos ((JsonObject) json ["quux"]) ["baz"] que he usado en C# 3.5.

Algunas investigaciones básicas muestran que Scala no tiene funciones de lenguaje dedicadas que admitan el enlace tardío. Sin embargo, hay tantos trucos que quizás se puedan usar juntos para crear una emulación tolerable del código mostrado arriba (o incluso para ser mejor, estoy casi seguro de que esto es posible). ¿Podría, por favor, aconsejarme algo aquí?

Respuesta

15

Una útil biblioteca JSON para Scala es lift-json, que es un componente independiente de Lift Web Framework.

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

Es compatible con la extracción de las clases, el análisis y una DSL para la creación de JSON.

La página que he vinculado tiene un tutorial completo, así que no solo copiaré y pegaré.

+1

ascensor-JSON es grande si se está ejecutando en el servidor ... por desgracia su dependencia de scalap y por lo tanto scala-compilador significa que puede ser una gran parte del o de bytes si está footprint- sensible. –

6

Definitivamente debe echarle un vistazo a sjson. Aquí ->sjson on github Estoy usando la implementación basada en la clase de tipo, que puede leer aquí ->some examples Si tiene un recorrido por el código, hay algunos trucos scala realmente interesantes. Esto debería darle lo que está buscando con respecto al n. ° 2. SJSON envuelve dispatch-json, que creo que proporciona integración a lift-json (mencionado anteriormente). Tanto dispatch-json/lift-json debería darle lo que está buscando en el n. ° 1. Por lo que vale, he estado usando sjson en un gran proyecto y está yendo nadando. Y el caballero detrás del proyecto ha sido bastante sorprendente y apoya el proyecto muy bien.

2

Como han señalado otros, hay muchas opciones.Más allá de los mencionados, la mayoría de las bibliotecas de procesamiento Java JSON también deberían funcionar con Scala, con diversos niveles de conveniencia (in) para lenguajes JVM que no sean Java (como Scala, Clojure, Groovy).

Los que son más potentes en términos de enlace de datos son Jackson, GSON y FlexJSON. Una posibilidad es comprobarlos y ver si puede ayudar a mejorar la interoperabilidad: Scala, por ejemplo, tiene una serie de tipos de datos "exóticos" que se beneficiarían del manejo explícito (más allá del manejo de objetos java 'estándar' que admiten las librerías).)

1

Si quieres algo realmente dinámico en Scala, aquí está: 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. 

Ahora, es una característica experimental, y no tan fuerte como el DLR .NET.

Casbah the scala-mongodb-driver lo ha intentado.

+0

Los rasgos dinámicos se han lanzado oficialmente como parte de Scala 2.10. – clemp6r

5

He flotaba entre usar lift-json y diversas variantes de sjson (por ejemplo dabasishg/sjson) y más recientemente Jerkson (una envoltura Scala en Jackson).

A los efectos de la serialización de objetos y deserialización sigo en la búsqueda de Jerkson requerir al menos ajustes para conseguir un trabajo hecho, por ejemplo, me acaban de codificación de una sencilla serialización de objetos con un case class que tiene este aspecto:

import org.joda.time.LocalDate 

case class UserStatus(subscriptionEndDate: LocalDate = null) 

tuve varios errores con tanto lift-json y sjson pero jerkson acaba de realizar con:

import com.codahale.jerkson.Json 

val jsonString = Json.generate(statusObject) 

y

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

interestinly suficiente el código para hacer esto en Scala es mucho más complicado que el de Java .. ninguna de esas respuestas dan un ruido solución libre como la biblioteca de Java Jackson excepción de Jerkson que se envuelve alrededor de 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