如何使用Scala生成Json

时间:2013-11-04 23:11:46

标签: scala

如何使用Scala生成下面的Json对象结构:

{
    "name": "flare",
        "children": [{
        "name": "analytics",
            "children": [{
            "name": "cluster",
                "children": [{
                "name": "AgglomerativeCluster",
                "size": 3938
            }, {
                "name": "CommunityStructure",
                "size": 3812
            }, {
                "name": "HierarchicalCluster",
                "size": 6714
            }, {
                "name": "MergeEdge",
                "size": 743
            }]
        }, {
            "name": "graph",
                "children": [{
                "name": "BetweennessCentrality",
                "size": 3534
            }, {
                "name": "LinkDistance",
                "size": 5731
            }, {
                "name": "MaxFlowMinCut",
                "size": 7840
            }, {
                "name": "ShortestPaths",
                "size": 5914
            }, {
                "name": "SpanningTree",
                "size": 3416
            }]
        }, {
            "name": "optimization",
                "children": [{
                "name": "AspectRatioBanker",
                "size": 7074
            }]
        }]
    }, {
        "name": "animate",
            "children": [{
            "name": "Easing",
            "size": 17010
        }, {
            "name": "FunctionSequence",
            "size": 5842
        }, {
            "name": "interpolate",
                "children": [{
                "name": "ArrayInterpolator",
                "size": 1983
            }, {
                "name": "ColorInterpolator",
                "size": 2047
            }, {
                "name": "DateInterpolator",
                "size": 1375
            }, {
                "name": "Interpolator",
                "size": 8746
            }, {
                "name": "MatrixInterpolator",
                "size": 2202
            }, {
                "name": "NumberInterpolator",
                "size": 1382
            }, {
                "name": "ObjectInterpolator",
                "size": 1629
            }, {
                "name": "PointInterpolator",
                "size": 1675
            }, {
                "name": "RectangleInterpolator",
                "size": 2042
            }]
        }, {
            "name": "ISchedulable",
            "size": 1041
        }, {
            "name": "Parallel",
            "size": 5176
        }, {
            "name": "Pause",
            "size": 449
        }, {
            "name": "Scheduler",
            "size": 5593
        }, {
            "name": "Sequence",
            "size": 5534
        }, {
            "name": "Transition",
            "size": 9201
        }, {
            "name": "Transitioner",
            "size": 19975
        }, {
            "name": "TransitionEvent",
            "size": 1116
        }, {
            "name": "Tween",
            "size": 6006
        }]
    }, {
        "name": "data",
            "children": [{
            "name": "converters",
                "children": [{
                "name": "Converters",
                "size": 721
            }, {
                "name": "DelimitedTextConverter",
                "size": 4294
            }, {
                "name": "GraphMLConverter",
                "size": 9800
            }, {
                "name": "IDataConverter",
                "size": 1314
            }, {
                "name": "JSONConverter",
                "size": 2220
            }]
        }, {
            "name": "DataField",
            "size": 1759
        }, {
            "name": "DataSchema",
            "size": 2165
        }, {
            "name": "DataSet",
            "size": 586
        }, {
            "name": "DataSource",
            "size": 3331
        }, {
            "name": "DataTable",
            "size": 772
        }, {
            "name": "DataUtil",
            "size": 3322
        }]
    }, {
        "name": "display",
            "children": [{
            "name": "DirtySprite",
            "size": 8833
        }, {
            "name": "LineSprite",
            "size": 1732
        }, {
            "name": "RectSprite",
            "size": 3623
        }, {
            "name": "TextSprite",
            "size": 10066
        }]
    }, {
        "name": "flex",
            "children": [{
            "name": "FlareVis",
            "size": 4116
        }]
    }, {
        "name": "physics",
            "children": [{
            "name": "DragForce",
            "size": 1082
        }, {
            "name": "GravityForce",
            "size": 1336
        }, {
            "name": "IForce",
            "size": 319
        }, {
            "name": "NBodyForce",
            "size": 10498
        }, {
            "name": "Particle",
            "size": 2822
        }, {
            "name": "Simulation",
            "size": 9983
        }, {
            "name": "Spring",
            "size": 2213
        }, {
            "name": "SpringForce",
            "size": 1681
        }]
    }]
};
}

这是我到目前为止所做的:

object DendorgramTORecursive {

  def getObject = {

    val topLevelNode = new com.data.recursive.DendogramVO
    topLevelNode.setName("flare")

    val level1Node = new com.data.recursive.Children
    level1Node.setName("analytics")

    val level1NodeData = new java.util.ArrayList[com.data.recursive.Children]()
    level1NodeData.add(level1Node);

    level1Node.setChildren(level1NodeData)

    //topLevelNode.setChildren(level1Node)

    topLevelNode
  }

}

package com.data.recursive;

import java.util.List;

public class DendogramVO {
    private List<Children> children;
    private String name;

    public List<Children> getChildren() {
        return this.children;
    }

    public void setChildren(List<Children> children) {
        this.children = children;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

package com.data.recursive;

import java.util.List;

public class Children {

    private List<Children> children;
    private String name;

    public List<Children> getChildren() {
        return children;
    }

    public void setChildren(List<Children> children) {
        this.children = children;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

返回json:

"{"children":[{"children":[{"name":"cluster","children":[{"name":"AgglomerativeCluster","size":3938},{"name":"TestCLuster","size":3938}]}],"name":"analytics"}],"name":"flare"}"

这看起来很麻烦,我觉得应该有一个更干净的方法吗?

5 个答案:

答案 0 :(得分:2)

建议你去coursera.org学习新课程:反应式编程原理。

在第一堂课中,有一个很好的Json演讲。

abstract class JSON
case class JSeq (elems: List[JSON]) extends JSON
case class JObj (bindings: Map[String, JSON]) extends JSON
case class JNum (num: Double) extends JSON
case class JStr (str: String) extends JSON
case class JBool(b: Boolean) extends JSON
case object JNull extends JSON


val data = JObj(Map(
  ”firstName” -> JStr(”John”),
  ”lastName” -> JStr(”Smith”),
  ”address” -> JObj(Map(
  ”streetAddress” -> JStr(”21 2nd Street”),
  ”state” -> JStr(”NY”),
  ”postalCode” -> JNum(10021)
)),
  ”phoneNumbers” -> JSeq(List(
  JObj(Map(
    ”type” -> JStr(”home”), ”number” -> JStr(”212 555-1234”)
  )),
  JObj(Map(
    ”type” -> JStr(”fax”), ”number” -> JStr(”646 555-4567”)
  )) )) ))

def show(json: JSON): String = json match {
  case JSeq(elems) =>
    ”[” + (elems map show mkString ”, ”) + ”]”
  case JObj(bindings) =>
    val assocs = bindings map {
      case (key, value) => ”\”” + key + ”\”: ” + show(value)
    }
    ”{” + (assocs mkString ”, ”) + ”}”
  case JNum(num) => num.toString
  case JStr(str) => ’\”’ + str + ’\”’
  case JBool(b) => b.toString
  case JNull => ”null”
}

答案 1 :(得分:1)

使用JSON4S,您可以使用简单的案例类:

case class Node(name: String, children: Option[List[Node]], size: Option[Int])

以下是如何构建Node个对象的树并打印生成的JSON:

object WriteJson extends App {
  import org.json4s.DefaultFormats
  import org.json4s.native.Serialization.{write, writePretty}

  val node1 = Node("AgglomerativeCluster", None, Some(3938))
  val node2 = Node("cluster", Some(List(node1)), None)
  val node3 = Node("analytics", Some(List(node2)), None)
  val node4 = Node("flare", Some(List(node3)), None)

  implicit val formats = DefaultFormats
  println(writePretty(node4))
}

这就是你读JSON的方法:

object ReadJson extends App {
  import org.json4s._
  import org.json4s.native.JsonMethods._

  val json =
    """
      |{
      |    "name": "flare",
      |    "children": [
      |        {
      |            "name": "analytics",
      |            "children": [
      |                {
      |                    "name": "cluster",
      |                    "children": [
      |                        {
      |                            "name": "AgglomerativeCluster",
      |                            "size": 3938
      |                        }
      |                    ]
      |                },
      |            ]
      |        }
      |    ]
      |}
    """.stripMargin

  implicit val formats = DefaultFormats
  val node = parse(json).extract[Node]
  println(node)  // Node(flare,Some(List(Node(analytics,Some(List(Node(cluster,Some(List(Node(AgglomerativeCluster,None,Some(3938)))),None))),None))),None)
}

Node类适用于所有值,因为两个不同的成员(childrensize)都包含Option。您可以使用isDefined来确定某个值是否包含数据,例如node.children.isDefined

答案 2 :(得分:0)

我使用Google GSON库以及我写的一些helper functions。它允许一些有点酷,几乎是文字的JSON语法,如下所示。

    JSON(
        "lis" -> List("", true, 2.0, 3L, JSON(), null),
        "obj" -> JSON(
            "nested_key" -> JSON()
        )
    )

答案 3 :(得分:0)

scala pickling将转换为JSON和从JSON转换。我认为这是一个Typesafe项目。

答案 4 :(得分:0)

使用Genson,您可以轻松地将scala Map / Seq或case类映射到Json并返回。

import com.owlike.genson.defaultGenson_

val json = toJson(Map("name" -> "foo"))
val value = fromJson[Map[String, String](json)

此外,它可能更多的是品味问题,但Genson并没有像其他lib一样大量使用implicits。例如,您不会使用implicits配置它,而是使用更经典的构建器,使您的代码更具可读性。

import com.owlike.genson._

object CustomGenson {
  lazy val customGenson = new ScalaGenson(
    new GensonBuilder()
      .useIndentation(true)
      .useDateAsTimestamp(true)
      .withBundle(new JodaTimeBundle())
      .create()
  )
}

// then just import it in the places you want to use this instance instead of the default one
import CustomGenson.customGenson._