Scala 返回任何val的列表/序列的json实体解码

Scala 返回任何val的列表/序列的json实体解码,scala,circe,http4s,Scala,Circe,Http4s,我正在使用http4s构建应用程序的后端。在应用程序中,我从外部api(不是我正在使用的api)接收json响应。api响应如下所示 json响应: `{ "datatable" : { "data" : [["AAPl", "MRT", "2020-03-20", 123, 123, 12.4, 233, 3234],

我正在使用http4s构建应用程序的后端。在应用程序中,我从外部api(不是我正在使用的api)接收json响应。api响应如下所示

json响应:

     `{
"datatable" : {
             "data" : [["AAPl", "MRT", "2020-03-20", 123, 123, 12.4, 233, 3234], 
                      ["AAPl", "MRT", "2020-03-20", 123, 123, 12.4, 233, 3234]],
              "meta": {
                      "next_date : null
              }
}`

我的问题是? 有人能告诉我如何创建实体解码器和实体编码器来解码模式吗。我似乎能让它发挥作用

目前我有:

  object Stocks {

   case class tickerInfo(ticker: String, dim:String, date: String, a: Int, b: Int, c: Float, d: Int, e: Int)

   case class data(data: Seq[tickerInfo])

   case class meta(next_date : Option[String])

   case class table(data: data, meta:meta)

   case class stockInfo(datatable:table)


  object stockInfo {
    implicit def stockInfoEntityDecoder[F[_]:Sync]: EntityDecoder [F, stockInfo] = jsonOf
    implicit def stockInfoEntityEncoder[F[_] : Applicative]: EntityEncoder[F, stockInfo] = jsonEncoderOf
     }

     val decodedJson = C.expect[stockInfo](GET(Uri.uri("www.externalApi.com")
     }
但这不起作用。请有人告诉我哪里出了问题

我得到一个运行时错误(不是编译错误)。这是一个http4s错误,上面写着-InvalidMessageBodyFailure

谢谢

您需要:

  • 创建一个数据模型,大概由一些案例类和可能密封的特征组成。此数据模型的外观取决于您正在使用的外部API
  • 为此数据模型创建JSON解码器。这些应该放在case类的伴随对象中,因为这将允许编译器在需要时找到它们,而无需导入任何内容
  • 使用http4s电路库将这些解码器与http4s集成
    如果所有操作都正确,那么应该能够使用检索数据,例如。g<代码>httpClient.expect[YourModelClass](Uri.Uri(“http://somewhere.com/something/)欢迎光临!我可能会从里面开始,然后找到你的出路:

    因此,对于
    data
    数组中的元素,可能类似(我猜是在域中):

    案例类股票(
    名称:String,
    玛特:字符串,
    datePosted:LocalDate,
    答:Int,
    b:Int,
    价格:双倍,
    c:Int,
    d:Int
    )
    
    使用Circe's应该可以很好地处理这个问题

    数据看起来像是一组分解元素的数组?因此,如果是这样的话,您可能需要编写一些提取逻辑来手动转换为内部对象。控制器中的类似内容可能会有所帮助:

    
    元素匹配{
    案例名称::集市::日期::a::b::价格::c::d::无=>库存(名称、集市、日期、a、b、价格、c、d)
    大小写无效@\=>log.warn(s“无效记录:$invalid”)
    }
    
    希望上面的代码片段能返回一些有用的东西,比如一个或[E,A],等等

    最后,您需要外部JSON的对象。一些易于捕获的内容,例如
    案例类externalapirest(dataTable:T)
    ,其中T是适合上述案例的类型。在最坏的情况下列出[字符串]?
    希望这有帮助!如果您遇到了任何特定错误,请告诉我。您的模型中有几个错误,但主要问题是circe无法将JSON数组自动解码为案例类。
    如果无法修改数据源,则需要创建自己的自定义编解码器

    object Stocks {
      final case class TickerInfo(ticker: String, dim: String, date: String, a: Int, b: Int, c: Float, d: Int, e: Int)
    
      final case class Meta(next_date : Option[String])
      final case class Table(data: List[TickerInfo], meta: Meta)
      final case class StockInfo(datatable: Table)
      
      object StockInfo {
        implicit final val TickerInfoDecoder: Decoder[TickerInfo] = Decoder[List[Json]].emap {
          case ticker :: dim :: date :: a :: b :: c :: d :: e :: Nil =>
            (
              ticker.as[String],
              dim.as[String],
              date.as[String],
              a.as[Int],
              b.as[Int],
              c.as[Float],
              d.as[Int],
              e.as[Int]
            ).mapN(TickerInfo).left.map(_.toString)
          
          case list =>
            Left(s"Bad number of fields in: ${list.mkString("[", ", ", "]")}")
        }
        
        implicit final val MetaDecoder: Decoder[Meta] = deriveDecoder
        implicit final val TableDecoder: Decoder[Table] = deriveDecoder
        implicit final val StockInfoDecoder: Decoder[StockInfo] = deriveDecoder
      }
    }
    
    (你可以看到它在工作,我把http4s部分放在了外面,因为它很难模仿,但这不重要)


    通过为每个字段提供更多有用的消息,可以改进该自定义编码器的错误报告。这是留给读者的练习。

    @LuisMiguelMejíaSuárez对此表示抱歉。我指的是http4s的实体解码器和实体编码器。我需要创建一个具有隐式实体解码器和实体编码器的对象来解码上面接收到的json。json的格式是我在上面创建的。我希望现在情况更清楚了?thanks@LuisMiguelMejíaSuárez我试图创建一个包含解码json的对象。与下面提供的答案类似,但他的答案并不完整,正如你所说。@LuisMiguelMejíaSuárez我现在已经更新了这个问题。thanks@LuisMiguelMejíaSuárez Its失败,出现一个http4s错误-InvalidMessageBodyFailure。我在过去遇到过这个错误,那是因为实体解码器无法解码传入的json。我已经更新了这个问题,以显示我当前的困境。如果您遇到invalidmessagebody错误,请提供帮助。你能帮忙吗?