简体   繁体   English

Scala Generics:无法将一个T实例写入HTTP响应。 尝试定义一个可写[T]

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM