Reputation: 15385
I have a Play framework controller method that returns either a Byte Array or a String based on the request header. Here is what it looks like:
def returnResponse = Action(parse.anyContent) {
request =>
println(request.body)
val buffer: RawBuffer = request.body.asRaw.get
val js: String = buffer.asBytes() match {
case Some(x) => new String(x, "UTF-8")
case None => scala.io.Source.fromFile(buffer.asFile).mkString
}
val resultJsonfut = scala.concurrent.Future { serviceCall.run(js) }
Async {
resultJsonfut.map(s => {
val out = if(request.headers.toSimpleMap.exists(_ == (CONTENT_ENCODING, "gzip"))) getBytePayload(s) else s
Ok(out)
})
}
}
I do not see any error in IntelliJ, but when I compile it, it fails with the following error:
Cannot write an instance of java.io.Serializable to HTTP response. Try to define a Writeable[java.io.Serializable]
Why is that? But however if I modify it a little bit to look like as below:
Async {
if(request.headers.toSimpleMap.exists(_ == (CONTENT_ENCODING, "gzip"))) {
resultJsonfut.map(s => Ok(getBytePayload(s)))
} else {
resultJsonfut.map(s => Ok(s))
}
}
It compiles fine. Any reasons why it behaves this way?
Upvotes: 2
Views: 841
Reputation: 23851
This happens because the return types of getBytePayload(s)
and s
are different.
Consider the simplier example:
val test = if (true) "1" else 0
The type of test
value will be Any
.
In general the if-else
in Scala produces the value and the type of this value will be the common type for both statements.
So considering the Int
type hierarchy looks like this: Int --> AnyVal --> Any
and the String
type hierarchy looks like this: String --> AnyRef --> Any
the first common type for them is Any
and in your case it seems to be a Serializable
Upvotes: 1