How do i specify spray Content-Type response header?

旧时模样 提交于 2019-12-30 08:19:29

问题


I understand that spray does that for me, but I still want to override it with my header, how can I override the header in the response?

My response looks like this:

case HttpRequest(GET, Uri.Path("/something"), _, _, _) =>
  sender ! HttpResponse(entity = """{ "key": "value" }""" // here i want to specify also response header i would like to explicitly set it and not get it implicitly

回答1:


If you still want to use spray can, then you have two options, based on that HttpResponse is a case class. The first is to pass a List with an explicit content type:

import spray.http.HttpHeaders._
import spray.http.ContentTypes._

def receive = {
    case HttpRequest(GET, Uri.Path("/something"), _, _, _) =>
      sender ! HttpResponse(entity = """{ "key": "value" }""", headers = List(`Content-Type`(`application/json`)))
  }

Or, the second way, is to use a method withHeaders method:

def receive = {
    case HttpRequest(GET, Uri.Path("/something"), _, _, _) =>
      val response: HttpResponse = HttpResponse(entity = """{ "key": "value" }""")
      sender ! response.withHeaders(List(`Content-Type`(`application/json`)))
  }

But still, like jrudolph said, it's much better to use spray routing, in this case it would look better:

def receive = runRoute {
    path("/something") {
      get {
        respondWithHeader(`Content-Type`(`application/json`)) {
          complete("""{ "key": "value" }""")
        }
      }
    }
  }

But spray makes it even easier and handles all (un)marshalling for you:

import spray.httpx.SprayJsonSupport._
import spray.json.DefaultJsonProtocol._

def receive = runRoute {
  (path("/something") & get) {
    complete(Map("key" -> "value"))
  }
}

In this case reponse type will be set to application/json by the spray itself.

Complete example for my comment:

class FullProfileServiceStack
  extends HttpServiceActor
     with ProfileServiceStack
     with ... {
  def actorRefFactory = context
  def receive = runRoute(serviceRoutes)
}

object Launcher extends App {
  import Settings.service._
  implicit val system = ActorSystem("Profile-Service")
  import system.log

  log.info("Starting service actor")
  val handler = system.actorOf(Props[FullProfileServiceStack], "ProfileActor")

  log.info("Starting Http connection")
  IO(Http) ! Http.Bind(handler, interface = host, port = port)
}



回答2:


The entity parameter of HttpResponse is actually of type HttpEntity and your string is only implicitly converted into an instance of HttpEntity. You can use one of the other constructors to specify a content-type. See the source for the possible constructors in the nightly version of spray.

Also if you use spray-routing, you can leave marshalling/unmarshalling to the infrastructure.




回答3:


In recent version of Spray (1.2.4 / 1.3.4), you may want to use respondWithMediaType. Here is the sample from the documentation :

val route =
  path("foo") {
    respondWithMediaType(`application/json`) {
      complete("[]") // marshalled to `text/plain` here
    }
  }

Note that while this overrides the HTTP header value, it will not override the marshaller used for serializing your content to the wire.

Therefore using a recent spray with spray routing, the original code would look like :

def receive = runRoute {
  path("/something") {
    get {
      respondWithMediaType(`application/json`) {
        complete("""{ "key": "value" }""")
      }
    }
  }
}



回答4:


To add to 4lex1v's answer, there is a very nice, short, simple, working (as of 4/15, scala 2.11.5) tutorial on the GeoTrellis site, including a build.sbt. The GeoTrellis pieces are also straightforward to eliminate for the purposes of this stack overflow question.

http://geotrellis.io/tutorials/webservice/spray/



来源:https://stackoverflow.com/questions/19396187/how-do-i-specify-spray-content-type-response-header

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!