[英]Scala Generics : Cannot write an instance of T to HTTP response. Try to define a Writeable[T]
Following code when written using generic give a compilation error. 使用泛型编写以下代码时会出现编译错误。
Without Generic 没有通用
def getData(id: String) = Action.async {
val items = getItems(id)
sendResult(items)
}
private def sendResult(result: Future[Any]) = {
result.map {
items => {
try {
val itemStr = items.asInstanceOf[String]
Ok(itemStr)
} catch {
case t: ClassCastException => InternalServerError(s"Casting Exception while processing output $t")
}
}
}.recover {
case t:TimeoutException => InternalServerError("Api Timed out")
case t: Throwable => InternalServerError(s"Exception in the api $t")
}
}
With Generic 使用Generic
def getData(id: String) = Action.async {
val items = getItems(id)
sendResult[String](items)
}
private def sendResult[T](result: Future[Any]) = {
result.map {
items => {
try {
val itemStr = items.asInstanceOf[T]
Ok(itemStr)
} catch {
case t: ClassCastException => InternalServerError(s"Casting Exception while processing output $t")
}
}
}.recover {
case t:TimeoutException => InternalServerError("Api Timed out")
case t: Throwable => InternalServerError(s"Exception in the api $t")
}
}
The code is part of play app's contorller method. 该代码是play app的contorller方法的一部分。 First one works fine.
第一个工作正常。 Second one gives following compilation error
第二个给出以下编译错误
Cannot write an instance of T to HTTP response.
无法将T实例写入HTTP响应。 Try to define a Writeable[T] [error] Ok(itemStr) [error]
尝试定义可写[T] [错误]确定(itemStr)[错误]
Using Any
with a generic function doesn't make much sense. 使用具有通用功能的
Any
没有多大意义。
private def sendResult[T](result: Future[Any])
// Should better be
private def sendResult[T](result: Future[T])
// ... also remove the unsafe cast
Then this T
needs to be provided an instance of Writeable
, so it can be written a Array[Byte]
over network. 然后此
T
需要被提供的一个实例Writeable
,因此它可以被写入一个Array[Byte]
通过网络。
// Either ...
private def sendResult[T: Writeable](result: Future[T])
// ... or ...
private def sendResult[T](result: Future[T])(implicit w: Writeable[T])
The Ok(...)
is calling the method apply[C](content: C)(implicit writeable: Writeable[C]): Result
on Status
class. Ok(...)
调用方法apply[C](content: C)(implicit writeable: Writeable[C]): Result
Status
类的apply[C](content: C)(implicit writeable: Writeable[C]): Result
。 You need to have an implicit value for Writeable[T]
in scope. 您需要在范围内具有
Writeable[T]
的隐式值。
As a side note, rather than using Future[Any], you may as well use Future[T] and remove the cast. 作为旁注,不如使用Future [Any],您也可以使用Future [T]并删除演员表。 Also you can use
Writes
for JSON serialization. 您还可以使用
Writes
for JSON序列化。
private def sendResult[T](result: Future[T])(implicit writeable: Writes[T]) = {
result.map {
items => {
Ok(Json.toJson(items))
}
}.recover {
case t:TimeoutException => InternalServerError("Api Timed out")
case t: Throwable => InternalServerError(s"Exception in the api $t")
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.