Handle response with unexpected content type as application / json?

When I try to get Amazon identification data like this

val pipeline: HttpRequest => Future[IdentityData] = sendReceive ~> unmarshal[IdentityData]
pipeline(Get("http://169.254.169.254/latest/dynamic/instance-identity/document"))

with the appropriate case and formatter class, I get the following exception

UnsupportedContentType (expected application / json)

because Amazon marks their response as text / plain content. They also do not care about the Accept header parameter. Is there an easy way to tell json spray to ignore this on unmarshalling?

+4
source share
3 answers

IdentityData ( case jsonFormat) amazon, json, text/plain , json , :

entity.asString.parseJson.convertTo(identityDataJsonFormat)
+3

,

def mapTextPlainToApplicationJson: HttpResponse => HttpResponse = {
  case r@ HttpResponse(_, entity, _, _) =>
    r.withEntity(entity.flatMap(amazonEntity => HttpEntity(ContentType(MediaTypes.`application/json`), amazonEntity.data)))
  case x => x
}

val pipeline: HttpRequest => Future[IdentityData] = sendReceive ~> mapTextPlainToApplicationJson ~> unmarshal[IdentityData]
pipeline(Get("http://169.254.169.254/latest/dynamic/instance-identity/document"))

, HttpResponse, .

+5

I came up with a cleaner version of @ yevgeniy-mordovkin's solution.

def setContentType(mediaType: MediaType)(r: HttpResponse): HttpResponse = {
  r.withEntity(HttpEntity(ContentType(mediaType), r.entity.data))
}

Using:

val pipeline: HttpRequest => Future[IdentityData] = (
       sendReceive
    ~> setContentType(MediaTypes.`application/json`)
    ~> unmarshal[IdentityData]
)
pipeline(Get("http://169.254.169.254/latest/dynamic/instance-identity/document"))
+1
source

Source: https://habr.com/ru/post/1546551/


All Articles