Serialization 静态资产的Lagom序列化

Serialization 静态资产的Lagom序列化,serialization,lagom,Serialization,Lagom,我正在开发Lagom微服务。除了肉,它还有一些静态文件(index.html、*.css、*.js和favicon.ico)。我知道如何使用Lagom的ServerServiceCall[Req,Res]设置响应的内容类型头。但是,如果指定String作为响应参数类型,则无论我在服务调用的主体中设置了什么,内容类型都将被覆盖为“text/plain”。如果我使用akka.util.ByteString,则内容类型将变为“应用程序/八位字节流” 我想这一定是因为String和ByteString的

我正在开发Lagom微服务。除了肉,它还有一些静态文件(index.html、*.css、*.js和favicon.ico)。我知道如何使用Lagom的
ServerServiceCall[Req,Res]
设置响应的内容类型头。但是,如果指定
String
作为响应参数类型,则无论我在服务调用的主体中设置了什么,内容类型都将被覆盖为“text/plain”。如果我使用
akka.util.ByteString
,则内容类型将变为“应用程序/八位字节流”

我想这一定是因为
String
ByteString
的序列化程序需要这样做。所以,我的问题是:要获得“text/html”、“text/css”、“application/javascript”和“image/vnd.microsoft.icon”,我应该做哪些响应类型?还是有一种更通用的方式来为Lagom的静态资产提供服务?关于这一点的文档出人意料地稀少

你喜欢这项工作吗

import akka.util.ByteString
import com.lightbend.lagom.scaladsl.api.transport.MessageProtocol
import com.lightbend.lagom.scaladsl.api.deser.MessageSerializer.NegotiatedSerializer

class ContentTypeSerializer(contentType: String, charset: String) extends NegotiatedSerializer[String, ByteString] {
  override val protocol = MessageProtocol(Some(contentType), Some(charset))
  def serialize(body: String) = ByteString.fromString(body, charset)
}

是的,这就解决了:

import akka.util.ByteString
import play.api.libs.json.Json
import scala.collection.immutable
import scala.util.control.NonFatal
import com.lightbend.lagom.scaladsl.api.transport._
import com.lightbend.lagom.scaladsl.api.deser.StrictMessageSerializer
import com.lightbend.lagom.scaladsl.api.deser.MessageSerializer.{NegotiatedDeserializer, NegotiatedSerializer}

class ContentTypeSerializer(contentType: String, charset: String) extends NegotiatedSerializer[String, ByteString] {
  override val protocol = MessageProtocol(Some(contentType), Some(charset))
  def serialize(body: String) = ByteString.fromString(body, charset)
}

object ContentTypeSerializer {
  val Json = "application/json"
  val Js = "application/javascript"
  val Icon = "image/vnd.microsoft.icon"
  val Html = "text/html"
  val Css = "text/css"

  val JsonSerializer = new ContentTypeSerializer(ContentTypeSerializer.Json, "utf-8")
}

class JsonTextDeserializer extends NegotiatedDeserializer[String, ByteString] {
  def deserialize(bytes: ByteString) =
    try {
      Json.parse(bytes.iterator.asInputStream).as[String]
    } catch {
      case NonFatal(e) => throw DeserializationException(e)
    }
}

object ResponseSerializer extends StrictMessageSerializer[String] {
  override val acceptResponseProtocols = List(
    MessageProtocol(Some(ContentTypeSerializer.Json)),
    MessageProtocol(Some(ContentTypeSerializer.Html)),
    MessageProtocol(Some(ContentTypeSerializer.Icon)),
    MessageProtocol(Some(ContentTypeSerializer.Css)),
    MessageProtocol(Some(ContentTypeSerializer.Js))
  )

  val serializerForRequest = ContentTypeSerializer.JsonSerializer

  def deserializer(protocol: MessageProtocol) = protocol.contentType match {
    case Some(ContentTypeSerializer.Json) | None =>
      new JsonTextDeserializer
    case _ =>
      throw UnsupportedMediaType(protocol, MessageProtocol(Some("text/plain")))
  }

  def serializerForResponse(accepted: immutable.Seq[MessageProtocol]) = accepted match {
    case Nil => ContentTypeSerializer.JsonSerializer
    case protocols => protocols.collectFirst {
      case MessageProtocol(Some(ContentTypeSerializer.Json), charset, _) =>
        new ContentTypeSerializer(ContentTypeSerializer.Json, charset.getOrElse("utf-8"))
      case MessageProtocol(Some(ContentTypeSerializer.Html), charset, _) =>
        new ContentTypeSerializer(ContentTypeSerializer.Html, charset.getOrElse("utf-8"))
      case MessageProtocol(Some(ContentTypeSerializer.Icon), charset, _) =>
        new ContentTypeSerializer(ContentTypeSerializer.Icon, charset.getOrElse("utf-8"))
      case MessageProtocol(Some(ContentTypeSerializer.Css), charset, _) =>
        new ContentTypeSerializer(ContentTypeSerializer.Css, charset.getOrElse("utf-8"))
      case MessageProtocol(Some(ContentTypeSerializer.Js), charset, _) =>
        new ContentTypeSerializer(ContentTypeSerializer.Js, charset.getOrElse("utf-8"))
    }.getOrElse {
      throw NotAcceptable(accepted, MessageProtocol(Some("text/plain")))
    }
  }
}