我有json4s跟随Scala控制台会话,我试图从解析的json中提取String值:
scala> import org.json4s._
import org.json4s._
scala> import org.json4s.native.JsonMethods._
import org.json4s.native.JsonMethods._
scala> val s = """ {"a": "hello"} """
s: String = " {"a": "hello"} "
scala> val json = parse(s)
json: org.json4s.JValue = JObject(List((a,JString(hello))))
scala> json \ "a"
res0: org.json4s.JValue = JString(hello)
scala> res0.extract[String]
<console>:17: error: No org.json4s.Formats found. Try to bring an instance of org.json4s.Formats in scope or use the org.json4s.DefaultFormats.
res0.extract[String]
^
scala> import org.json4s.Formats._
import org.json4s.Formats._
scala> res0.extract[String]
<console>:20: error: No org.json4s.Formats found. Try to bring …Run Code Online (Sandbox Code Playgroud) 是否有可能使json4s在缺少必填字段时不抛出异常?
当我从原始json字符串"提取"对象时,它会像这样抛出异常
org.json4s.package$MappingException: No usable value for pager
No usable value for rpp
Did not find value which can be converted into byte
at org.json4s.reflect.package$.fail(package.scala:98)
at org.json4s.Extraction$ClassInstanceBuilder.org$json4s$Extraction$ClassInstanceBuilder$$buildCtorArg(Extraction.scala:388)
at org.json4s.Extraction$ClassInstanceBuilder$$anonfun$11.apply(Extraction.scala:396)
Run Code Online (Sandbox Code Playgroud)
是否可以让它为空?
我正在写一个Customer Serializer.在那个Serializer中我想以某种方式说:"这件事你已经知道如何序列化".
我目前的方法看起来像这样:
import org.json4s.native.Serialization._
import org.json4s.JsonDSL.WithBigDecimal._
object WindowSerializer extends CustomSerializer[Window](format =>
( [omitted],
{
case Window(frame, size) =>
( "size" -> size ) ~
( "frame" -> parse(write(frame)) )
}))
Run Code Online (Sandbox Code Playgroud)
这parse(write(frame))东西是既丑陋和低效.如何解决?
我有一些源对象src,想从中得到一个JValue.json4s的所有示例和文档似乎都围绕着获取JSON编码的字符串,如下所示:
def encodeJson(src: AnyRef): String = {
import org.json4s.NoTypeHints
import org.json4s.JsonDSL.WithDouble._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization
import org.json4s.jackson.Serialization.write
implicit val formats = Serialization.formats(NoTypeHints)
write(src)
}
Run Code Online (Sandbox Code Playgroud)
如果我只想要最终结果,这很好,但我更愿意写一个:
def encodeJson(src: AnyRef): JValue
Run Code Online (Sandbox Code Playgroud)
这似乎ToJsonWritable[T]是我想要使用的,但我似乎无法找到一个实现Writer[AnyRef](也不能找到json4s的scaladocs,它只会告诉我实现).
假设我有一个带有以下设置的案例类:
case class Place(id:java.util.UUID, name:String)
Run Code Online (Sandbox Code Playgroud)
我可以为这种类型编写一个(working!)序列化器,如下所示:
class placeSerializer extends CustomSerializer[Place]( format => (
{
case JObject(JField("id", JString(s)) :: JField("name",JString(x)) :: Nil ) =>
Place(UUID.fromString(s), x)
},
{
case x:Place =>
JObject(
JField("id", JString(x.id.toString())) ::
JField("name", JString(x.name)) :: Nil)
}
)
)
Run Code Online (Sandbox Code Playgroud)
但假设我的case类最终有更多的字段,这可能导致我用AST枚举对象的整个结构,创建一些非常详细的东西来编码基元.
json4s似乎具有只能在特定字段上起作用的字段序列化程序,其中包含样板方法以轻松转换名称和丢弃字段.然而,这些对他们的以下签名serialize和deserialize部分功能:
case class FieldSerializer[A: Manifest](
serializer: PartialFunction[(String, Any), Option[(String, Any)]] = Map(),
deserializer: PartialFunction[JField, JField] = Map()
)
Run Code Online (Sandbox Code Playgroud)
由于JField(代表键的类型 - >来自json的val)是它自己的类型而不是它的子类JValue,我如何组合这两种类型的序列化器来正确地将id键的名称编码为a UUID,同时保持默认处理其他字段(原始数据类型).
基本上我想要一个理解其中的字段的格式链Place是一个UUID,而不必为所有DefaultFormats已经处理的字段指定AST结构. …
我正在使用json4s来处理我的Scala代码中的JSON对象.我想将JSON数据转换为内部表示.以下学习测试说明了我的问题:
"Polimorphic deserailization" should "be possible" in {
import org.json4s.jackson.Serialization.write
val json =
"""
|{"animals": [{
| "name": "Pluto"
| }]
|}
""".stripMargin
implicit val format = Serialization.formats(ShortTypeHints(List(classOf[Dog], classOf[Bird])))
val animals = parse(json) \ "animals"
val ser = write(Animals(Dog("pluto") :: Bird(canFly = true) :: Nil))
System.out.println(ser)
// animals.extract[Animal] shouldBe Dog("Pluto") // Does not deserialize, because Animal cannot be constructed
}
Run Code Online (Sandbox Code Playgroud)
假设有一个JSON对象,它有一个动物列表.Animal是一种抽象类型,因此无法实例化.相反,我想解析JSON结构以返回其中一个Dog或Bird对象.他们有不同的签名:
case class Dog(name: String) extends Animal
case class Bird(canFly: Boolean) extends Animal
Run Code Online (Sandbox Code Playgroud)
因为它们的签名是不同的,所以可以在JSON对象中没有类Tag的情况下识别它们.(确切地说,我收到的JSON结构不提供这些标签). …
我目前正在从不同的数据源中提取一些度量标准,并将它们存储在类型的映射中,Map[String,Any]其中密钥对应于度量标准名称,值对应于度量标准值.我需要这或多或少是通用的,这意味着值类型可以是基本类型或基元类型列表.
我想将此映射序列化为JSON格式的字符串,为此我使用json4s库.事情是它似乎不可能,我没有看到可能的解决方案.我希望像下面这样的东西开箱即用:)
val myMap: Map[String,Any] = ... // extract metrics
val json = myMap.reduceLeft(_ ~ _) // create JSON of metrics
Run Code Online (Sandbox Code Playgroud)
通过导航源代码我已经看到json4s为了变换原始类型来提供隐式转换JValue的和也将转换Traversable[A]/Map[String,A]/Option[A]到JValue的(被购自的隐式转换的限制下A到JValue,这是我明白它实际上意味着A是一个基本类型).该~运营商提供构建的一个很好的方式JObject的出来JField的,这仅仅是一个类型别名(String, JValue).
在这种情况下,映射值类型是Any,因此不会发生隐式转换,因此编译器会抛出以下错误:
value ~ is not a member of (String, Any)
[error] val json = r.reduceLeft(_ ~ _)
Run Code Online (Sandbox Code Playgroud)
我想要完成的是什么解决方案?
我正在学习Json4s库.
我有一个像这样的json片段:
{
"records":[
{
"name":"John Derp",
"address":"Jem Street 21"
},
{
"name":"Scala Jo",
"address":"in my sweet dream"
}
]
}
Run Code Online (Sandbox Code Playgroud)
而且,我有Scala代码,它将json字符串转换为List of Maps,如下所示:
import org.json4s._
import org.json4s.JsonAST._
import org.json4s.native.JsonParser
val json = JsonParser.parse( """{"records":[{"name":"John Derp","address":"Jem Street 21"},{"name":"Scala Jo","address":"in my sweet dream"}]}""")
val records: List[Map[String, Any]] = for {
JObject(rec) <- json \ "records"
JField("name", JString(name)) <- rec
JField("address", JString(address)) <- rec
} yield Map("name" -> name, "address" -> address)
println(records)
Run Code Online (Sandbox Code Playgroud)
records屏幕的输出给出了:
列表(地图(名称 - > John Derp,地址 …
我试图在我的火花工作中解析json时遇到了一个问题.我使用spark 1.1.0,json4s和Cassandra Spark Connector.抛出的异常是:
java.io.NotSerializableException: org.json4s.DefaultFormats
检查DefaultFormats伴随对象,并且使用此堆栈问题,很明显无法序列化DefaultFormats.问题是现在该做什么.
通过添加关键字transient,我可以看到这张票显然在spark代码库中解决了这个问题,但我不确定如何或在何处将它应用到我的案例中.解决方案是仅在执行程序上实例化DefaultFormats类,以避免序列化在一起吗?是否有人们正在使用scala/spark的另一个JSON解析库?我最初尝试使用jackson本身,但遇到了一些我无法轻易解决的注释错误,json4s开箱即用.这是我的代码:
import org.json4s._
import org.json4s.jackson.JsonMethods._
implicit val formats = DefaultFormats
val count = rdd.map(r => checkUa(r._2, r._1)).reduce((x, y) => x + y)
Run Code Online (Sandbox Code Playgroud)
我在checkUa函数中进行json解析.我试图让计数懒惰,希望它以某种方式延迟执行,但它没有效果.也许在checkUA中移动隐式val?任何建议都非常感谢.
我有一个嵌套的json,其结构未定义.由于我从远程文件中读取,因此每次运行时都可能不同.我需要将这个json转换为类型的地图Map[String, Any].我试着研究json4s和jackson解析器,但它们似乎没有解决我的这个问题.有谁知道我怎么能做到这一点?
示例字符串:
{"body":{
"method":"string",
"events":"string",
"clients":"string",
"parameter":"string",
"channel":"string",
"metadata":{
"meta1":"string",
"meta2":"string",
"meta3":"string"
}
},
"timestamp":"string"}
Run Code Online (Sandbox Code Playgroud)
嵌套级别可以是任意的,也不是预定义的.
为了帮助解决这个问题:
我有一个Map [String,Any],我需要将它作为备份存储在一个文件中.所以我将它转换为json字符串并将其存储在一个文件中.现在,每当我获得新数据时,我需要从文件中获取json,再次将其转换为地图并执行一些计算.我无法将地图存储在内存中,因为如果我的工作失败,我会失去它.
我需要一个解决方案,将json字符串转换回我转换之前的原始地图.