2017-06-16 103 views
0

我建立一个非常简单的服务,应该返回一棵树一样通过递归情况下,类中定义的结构:上运行时编码的递归数据结构为JSON与瑟茜http4s

case class Node(id: Int, name: String, children: Seq[Node] = Seq()) 

但由于某些原因,我一直得到一个以下编译错误:

Error:(24, 70) could not find implicit value for parameter encoder: io.circe.Encoder[Seq[com.ansarada.ds.docviewer.server.Main.Node]]
implicit val nodesEncoder: EntityEncoder[Seq[Node]] = jsonEncoderOf[Seq[Node]]

Error:(24, 70) not enough arguments for method jsonEncoderOf: (implicit encoder: io.circe.Encoder[Seq[com.ansarada.ds.docviewer.server.Main.Node]])org.http4s.EntityEncoder[Seq[com.ansarada.ds.docviewer.server.Main.Node]]. Unspecified value parameter encoder. implicit val nodesEncoder: EntityEncoder[Seq[Node]] = jsonEncoderOf[Seq[Node]]

的代码被编译,一旦我删除儿童元素定义,把一个节点到平面物体:

case class Node(id: Int, name: String) 

任何人都可以帮助我定义正确的Json编码器的情况下嵌套的孩子?

全码:

import org.http4s.circe._ 
import org.http4s.dsl._ 
import org.http4s.server.blaze.BlazeBuilder 
import org.http4s.server.{Server, ServerApp} 
import org.http4s.{EntityEncoder, HttpService} 

import scalaz.concurrent.Task 

object Main extends ServerApp { 
    import io.circe.generic.auto._ 
    import io.circe.syntax._ 

    case class Node(id: Int, name: String, children: Seq[Node] = Seq()) 

    def getNodes: Seq[Node] = Seq(
    Node(0, "#One"), 
    Node(1, "#Two"), 
    Node(2, "#Three") 
) 

    implicit val nodeEncoder: EntityEncoder[Node] = jsonEncoderOf[Node] 
    implicit val nodesEncoder: EntityEncoder[Seq[Node]] = jsonEncoderOf[Seq[Node]] 

    override def server(args: List[String]): Task[Server] = { 
    val nodesService = HttpService { 
     case _ @ GET -> Root/"nodes" => 
     Ok(getNodes.asJson) 
    } 

    BlazeBuilder 
     .bindHttp(8080, "localhost") 
     .mountService(nodesService, "/api") 
     .start 
    } 
} 

回答

0

确定。使用circe json annotations得到它的工作 - @JsonCodec。 步骤一步的指导来解决的问题如上所述:

  1. 先决条件 - 进口瑟茜lib目录下:

    "io.circe" %% "circe-core" % "0.8.0", 
    "io.circe" %% "circe-generic" % "0.8.0", 
    "io.circe" %% "circe-literal" % "0.8.0", 
    "io.circe" %% "circe-parser" % "0.8.0", 
    
  2. 打开自动编译器插件在您的build.sbt:

    autoCompilerPlugins := true 
    
  3. 添加scalamacros天堂编译插件:

    lazy val root = Project("root", file(".")) 
        .settings(
         addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.patch) 
    ) 
    
  4. 标注case类与@JsonCodec:

    @JsonCodec case class Node(id: Int, children: Seq[Node] = Seq()) 
    
  5. 角色响应于JSON:

    Ok(getNodes.asJson) 
    

完整代码段:

import org.http4s.circe._ 
import org.http4s.dsl._ 
import org.http4s.server.blaze.BlazeBuilder 
import org.http4s.server.{Server, ServerApp} 
import org.http4s.{EntityEncoder, HttpService} 

import scalaz.concurrent.Task 
object Main extends ServerApp { 
    import io.circe.generic.auto._ 
    import io.circe.syntax._ 

    @JsonCodec case class Node(id: Int, name: String, children: Seq[Node] = Seq()) 

    def getNodes: Seq[Node] = Seq(
    Node(0, "#One"), 
    Node(1, "#Two"), 
    Node(2, "#Three") 
) 

    override def server(args: List[String]): Task[Server] = { 
    val nodesService = HttpService { 
     case _ @ GET -> Root/"nodes" => 
     Ok(getNodes.asJson) 
    } 

    BlazeBuilder 
     .bindHttp(8080, "localhost") 
     .mountService(nodesService, "/api") 
     .start 
    } 
}