/ / Scala: Nie znaleziono serializatora Json dla typu Any - json, scala, playframework

Scala: Nie znaleziono serializatora Json dla typu Any - json, scala, playframework

Mam następujący kod. Oto schemat dla vesselFlagCountryDF

root
|-- flagcountry: string (nullable = true)
|-- max(count): long (nullable = true)
|-- min(count): long (nullable = true)
|-- avg(count): double (nullable = true)
|-- stddev_samp(count,0,0): double (nullable = false)

A oto kilka przykładowych wierszy:

+--------------------+----------+----------+----------+----------------------+
|         flagcountry|max(count)|min(count)|avg(count)|stddev_samp(count,0,0)|
+--------------------+----------+----------+----------+----------------------+
|              Cyprus|        65|        46|      55.0|      9.40744386111339|
|          Luxembourg|         3|         1|       2.5|    0.9999999999999999|
|                Niue|         5|         3|       4.4|    0.8944271909999159|
|           Palestine|         2|         1|      1.25|   0.49999999999999994|
|              Norway|        30|        18|      23.4|     5.683308895353129|
|            Mongolia|        21|        15|      17.6|     2.302172886644268|
|            Dominica|         1|         1|       1.0|                   0.0|
|British Virgin Is...|         1|         1|       1.0|                   NaN|
+--------------------+----------+----------+----------+----------------------+

Teraz stddev („count”) może być Double lub Nan.

import play.api.libs.json.{JsValue, Json}

val vesselFlagCountryDF =
vtype.groupBy("flagcountry").agg(max("count"), min("count"), avg("count"),
stddev("count"))

vesselFlagCountryDF.collect().foreach(row => {
val flagCountry = row.getString(row.fieldIndex("flagcountry"))
val upper: Long = row.getLong(row.fieldIndex("max(count)"))
val lower: Long = row.getLong(row.fieldIndex("min(count)"))
val mean: Double = row.getDouble(row.fieldIndex("avg(count)"))
val stdDevWrapper: Any = row.get(row.fieldIndex("stddev_samp(count,0,0)"))
val stdDev = stdDevWrapper match {
case d: Double => d
case _  => "NaN"
}

val json: JsValue = Json.obj(
"type" -> "statistics",
"name" -> "vesselCountByFlagCountry",
"flagCountry" -> flagCountry,
"timeInterval" -> Json.obj("startTime" -> startTime, "endTime" -> endTime),
"upper" -> upper,
"lower" -> lower,
"mean" -> mean,
"stdDev" -> stdDev
)

W tej linii:

      "stdDev" -> stdDev

Pojawia się następujący błąd:

No Json serializer found for type Any. Try to implement an implicit Writes or
Format for this type.
[error]           "stdDev" -> stdDev

Jak najlepiej poradzić sobie z tym błędem?

Odpowiedzi:

4 dla odpowiedzi № 1

Poniższy termin można wywnioskować tylko jako Any ponieważ nie ma typu nadrzędnego do ujednolicenia Double i String, co nie jest zalecane.

val stdDev = stdDevWrapper match {
case d: Double => d
case _  => "NaN"
}

Z drugiej strony serializacja JSON działa tylko z wartościami wpisanymi, co nie ma miejsca w przypadku Any wartość.

The stdDev można refaktoryzować, aby bezpośrednio wpisać odpowiednią wartość JSON zgodnie ze sprawą.

val stdDev: JsValue = stdDevWrapper match {
case d: Double => Json.toJson(d)
case _  => Json.toJson("NaN")
}