我有一些json,其中包括一些被平铺成bson-ish格式的字段,如{"foo.bar" : "bash"}.我想将其转换为以下表示,{"foo" : { "bar" : "bash"}}并想知道在哪里进行这样的操作.使问题复杂化的是,可能存在需要正确合并的多个这样的字段,例如{"foo.bar" : "a", "foo.bash" : "b", "foo.baz" : "c"}- > {"foo" : { "bar" : "a", "bash" : "b", "baz" : "c"}}.
我正在尝试使用 scala json 库 Circe,将其包装在一个简单的特征中,以提供与 json 之间的转换,我有以下内容:
import io.circe.generic.auto._
import io.circe.parser._
import io.circe.syntax._
trait JsonConverter {
def toJson[T](t : T) : String
def fromJson[T](s: String) : T
}
case class CirceJsonConverter() extends JsonConverter{
override def toJson[T](t: T): String = t.asJson.noSpaces
override def fromJson[T](s: String): T = decode[T](s).getOrElse(null).asInstanceOf[T]
}
Run Code Online (Sandbox Code Playgroud)
这样做的目的是简单地能够使用任何对象调用 JsonConverter 并将其转换为 json 或从 json 转换为这样jsonConverter.toJson(0) must equalTo("0"),但是当我尝试编译它时,我得到以下结果:
[error] could not find implicit value for parameter encoder: io.circe.Encoder[T]
[error] override def toJson[T](t: T): String = t.asJson.noSpaces
[error] ^
[error] …Run Code Online (Sandbox Code Playgroud) 鉴于:
鉴于以下关于亚扪人:
@ import $ivy.`io.circe::circe-core:0.9.0`
@ import $ivy.`io.circe::circe-generic:0.9.0`
@ import $ivy.`com.chuusai::shapeless:2.3.3`
@ import shapeless.tag
import shapeless.tag
@ trait Foo
defined trait Foo
@ import io.circe._, io.circe.generic.semiauto._
import io.circe._, io.circe.generic.semiauto._
@ import shapeless.tag.@@
import shapeless.tag.@@
@ implicit def taggedTypeDecoder[A, B](implicit ev: Decoder[A]): Decoder[A @@ B] =
ev.map(tag[B][A](_))
defined function taggedTypeDecoder
Run Code Online (Sandbox Code Playgroud)
鉴于Foo:
@ case class F(x: String @@ Foo)
defined class F
Run Code Online (Sandbox Code Playgroud)
我可以召唤一个Decoder[String @@ Foo]:
@ Decoder[String @@ Foo]
res17: Decoder[String @@ Foo] = io.circe.Decoder$$anon$21@16b32e49
Run Code Online (Sandbox Code Playgroud)
但不是F: …
我正在尝试编码一个case类(其中一些属性也是case类),并且我将嵌套的case类名作为JSON中的键名。是否有一种简单的方法可以避免这种情况,而无需创建自定义编码器?嵌套类继承自密封特征。
我目前正在使用半自动推导。
以下工作表示例显示了我的问题:
case class A(foo: Int, bar: Sub)
sealed trait Sub
case class B(x: Int, y: Int) extends Sub
case class C(x: Int, y: Int, z: Int) extends Sub
import io.circe._, io.circe.generic.semiauto._
import io.circe.syntax._
implicit val bEncoder: Encoder[Sub] = deriveEncoder
implicit val aEncoder: Encoder[A] = deriveEncoder
A(123, B(8, 8)).asJson
A(456, C(8, 8, 8)).asJson
Run Code Online (Sandbox Code Playgroud)
而不是:
res0: io.circe.Json = {
"foo" : 123,
"bar" : {
"x" : 8,
"y" : 8
}
}
res1: io.circe.Json = {
"foo" : 456, …Run Code Online (Sandbox Code Playgroud) 假设我在 Scala 中有一个 ADT:
sealed trait Base
case class Foo(i: Int) extends Base
case class Baz(x: String) extends Base
Run Code Online (Sandbox Code Playgroud)
我想将这种类型的值编码到如下所示的 JSON 中:
{ "Foo": { "i": 10000 }}
{ "Baz": { "x": "abc" }}
Run Code Online (Sandbox Code Playgroud)
幸运的是,这正是编码 circe 的通用派生提供的!
scala> import io.circe.generic.auto._, io.circe.syntax._
import io.circe.generic.auto._
import io.circe.syntax._
scala> val foo: Base = Foo(10000)
foo: Base = Foo(10000)
scala> val baz: Base = Baz("abc")
baz: Base = Baz(abc)
scala> foo.asJson.noSpaces
res0: String = {"Foo":{"i":10000}}
scala> baz.asJson.noSpaces
res1: String = {"Baz":{"x":"abc"}}
Run Code Online (Sandbox Code Playgroud)
问题在于 circe 使用的编码器取决于我们正在编码的表达式的静态类型。这意味着,如果我们尝试直接解码案例类之一,我们将失去鉴别器: …
我正在阅读 circe 文档,但无法弄清楚如何处理以下问题。
我只想在主 JSON 对象中添加一个带有对象的字段。
{
Fieldalreadythere: {}
"Newfield" : {}
}
Run Code Online (Sandbox Code Playgroud)
我只想Newfield在对象中添加。为了提供一些上下文,我正在处理 Json-ld。我只想添加一个上下文对象。@context:{} 请参见下面的示例:
{
"@context": {
"@version": 1.1,
"xsd": "http://www.w3.org/2001/XMLSchema#",
"foaf": "http://xmlns.com/foaf/0.1/",
"foaf:homepage": { "@type": "@id" },
"picture": { "@id": "foaf:depiction", "@type": "@id" }
},
"@id": "http://me.markus-lanthaler.com/",
"@type": "foaf:Person",
"foaf:name": "Markus Lanthaler",
"foaf:homepage": "http://www.markus-lanthaler.com/",
"picture": "http://twitter.com/account/profile_image/markuslanthaler"
}
Run Code Online (Sandbox Code Playgroud)
我想添加上下文对象,仅此而已。
我怎么能用circe做到这一点。官方文档中的例子主要是讲修改值,但没有实际添加字段等。
我有以下案例类:
final case class Camel(firstName: String, lastName: String, waterPerDay: Int)
Run Code Online (Sandbox Code Playgroud)
和circe配置:
object CirceImplicits {
import io.circe.syntax._
import io.circe.generic.semiauto._
import io.circe.{Encoder, Decoder, Json}
import io.circe.generic.extras.Configuration
implicit val customConfig: Configuration =
Configuration.default.withSnakeCaseMemberNames.withDefaults
implicit lazy val camelEncoder: Encoder[Camel] = deriveEncoder
implicit lazy val camelDecoder: Decoder[Camel] = deriveDecoder
}
Run Code Online (Sandbox Code Playgroud)
没关系,在对此进行测试时:
val camel = Camel(firstName = "Camelbek", lastName = "Camelov", waterPerDay = 30)
private val camelJ = Json.obj(
"firstName" -> Json.fromString("Camelbek"),
"lastName" -> Json.fromString("Camelov"),
"waterPerDay" -> Json.fromInt(30)
)
"Decoder" must "decode camel types" in { …Run Code Online (Sandbox Code Playgroud) 当字段可以具有不同的原始值类型时,我在解析json时遇到问题。例如,我可以获取json:
{
"name" : "john",
"age" : 31
}
Run Code Online (Sandbox Code Playgroud)
也可以采用以下形式:
{
"name" : "john",
"age" : "thirty one"
}
Run Code Online (Sandbox Code Playgroud)
或以这种方式:
{
"name" : "john",
"age" : 31.0
}
Run Code Online (Sandbox Code Playgroud)
我希望能够将字段解析age为以下ADT实例:
sealed trait PrimitiveWrapper
case class IntWrapper(v: Int) extends PrimitiveWrapper
case class StringWrapper(v: String) extends PrimitiveWrapper
case class FloatWrapper(v: Float) extends PrimitiveWrapper
Run Code Online (Sandbox Code Playgroud)
所以最后我可以得到这样的东西:
case class Person(name: String, age: PrimitiveWrapper)
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?我找到了这个主题:如何在不区分对象的情况下使用circe解码ADT
但是在这种解决方案中,我们不解析原始字段。
我正在尝试为两个案例类生成编码器和解码器:
object EventBusCases {
case class ValuationRequest(function: RequestValue = ALL_DAY_VALS, interval: RequestValue = IntraDayIntervals.MIN_5)
implicit val requestDecoder: Decoder[ValuationRequest] = deriveDecoder[ValuationRequest]
implicit val requestEncoder: Encoder[ValuationRequest] = deriveEncoder[ValuationRequest]
case class ValuationResponse(values: List[Valuation], function: RequestValue)
implicit val responseDecoder: Decoder[ValuationResponse] = deriveDecoder[ValuationResponse]
implicit val responseEncoder: Encoder[ValuationResponse] = deriveEncoder[ValuationResponse]
}
Run Code Online (Sandbox Code Playgroud)
我不断收到这样的错误,但对于这两种情况:
could not find Lazy implicit value of type io.circe.generic.encoding.DerivedAsObjectEncoder[eventbus.eventBusCases.ValuationResponse]
我决定还尝试为这些类中的自定义类派生编码器和解码器,例如“Valuation”,但我在这些类上遇到了相同的错误。
我正在使用Circe 0.12.3这些Scala 2.12.8是我的 Circe 相关的 Scala 依赖项:
"com.beachape" %% "enumeratum" % "1.5.14",
"com.beachape" %% "enumeratum-circe" % "1.5.22",
"io.circe" %% "circe-core" …Run Code Online (Sandbox Code Playgroud) 我使用 Scala circe 库将案例类的对象转换为 JSON,并根据 JSON 表示Message创建对象。Message该类的实现如下:
import io.circe
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.parser
import io.circe.syntax._
object Message {
implicit val measurementDecoder = deriveDecoder[Message]
implicit val measurementEncoder = deriveEncoder[Message]
def fromJson(jsonString: String): Either[circe.Error, Message] =
parser.decode[Message](jsonString)
}
case class Message(id: Int, text: String) {
def toJson() = (this).asJson.noSpaces
def toJson2() = this.asJson.noSpaces // syntax error: No implicit arguments of type: Encoder[Message.this.type]
}
Run Code Online (Sandbox Code Playgroud)
我的观点是方法的实现toJson。虽然这个变体有效
import io.circe
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.parser
import io.circe.syntax._
object Message …Run Code Online (Sandbox Code Playgroud)