使用案例类别No Manifest的Scala Dynamic Parse Json可用于T

时间:2019-05-05 10:37:22

标签: scala generics

我有一个JSON字符串,并且创建了一个函数,该函数使用Scala JSON将此case class解析为对象。我编写了以下代码,以通用方式对其进行解析。但是,它给了我一个错误:

def getJsonObj[T](jsonString:String): T = {
    implicit val formats: DefaultFormats.type = DefaultFormats
      parse(jsonString).extract[T]
}

错误可以在下面找到:

Error:(19, 32) No Manifest available for T. 
parse(jsonString).extract[T] Error:(19, 32) not enough arguments for 
method extract: (implicit formats: org.json4s.Formats, implicit mf: 
scala.reflect.Manifest[T])T. Unspecified value parameter mf.
parse(jsonString).extract[T]

我找到了这个No Manifest available for Type,但是我不知道如何在我的代码中对其进行修复。另外,我发现thisSpark Scala - How to construct Scala Map from nested JSONScala: "No manifest available for type T"),但是我需要以通用的方式将case class传递给函数。这似乎是一个常见的问题,但是由于我是Scala的新手,所以我无法使用可用的答案来解决它。

另一点,我如何添加try-catch以查看其是否正确解析?

1 个答案:

答案 0 :(得分:6)

我认为这个答案解决了您的问题,Scala: “No manifest available for type T”。通过隐式传递清单类型方法很容易解决。我添加了一个代码示例和一个用于错误处理的简单函数。

  val jsonStr: String = """{"airports":[{"name":"sfo","score":1},{"name":"phx","score":1},{"name":"sjc","score":1}]}"""

  case class AirPortScores(name: String, score: Double)
  case class JsonRulesHandler(airports: List[AirPortScores])

  val json: JsonRulesHandler = getJsonObj[JsonRulesHandler](jsonStr)
  println(json)


  def getJsonObj[T](jsonString:String)(implicit m: Manifest[T]): T = {
    extractFrom(jsonString) match {
      case Success(jsonParsed) ⇒
        jsonParsed
      case Failure(exc) ⇒
        throw new IllegalArgumentException(exc)
    }
  }

  private def extractFrom[T](jsonString:String)(implicit m: Manifest[T]): Try[T] = {
    implicit val formats: DefaultFormats.type = DefaultFormats

    Try {
      parse(jsonString).extract[T]
    }
  }