4

そのようなAmazon IDデータを取得しようとすると

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

適切なケース クラスとフォーマッタを使用すると、次の例外が発生します。

UnsupportedContentType ('application/json' が必要です)

Amazon がレスポンスをtext/plainコンテンツ タイプとしてマークするためです。また、 Acceptヘッダー パラメータも気にしません。アンマーシャリング時にこれを無視するようにspray-jsonに指示する簡単な方法はありますか?

4

3 に答える 3

5

スプレーメールリストを掘り下げた後、機能する関数を書きました

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をインターセプトおよび変更できることです。

于 2014-06-30T13:47:59.197 に答える
3

有効な json である amazon レスポンスから一部IdentityData(定義済みのケース クラス)を抽出したい場合、コンテキスト タイプを使用すると、テキスト データを抽出し、json を解析してデータに変換できます。たとえば、次のようになります。jsonFormattext/plain

entity.asString.parseJson.convertTo(identityDataJsonFormat)
于 2014-06-30T14:13:22.180 に答える
1

@yevgeniy-mordovkinのソリューションのよりシンプルでクリーンなバージョンを思いつきました。

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

使用法:

val pipeline: HttpRequest => Future[IdentityData] = (
       sendReceive
    ~> setContentType(MediaTypes.`application/json`)
    ~> unmarshal[IdentityData]
)
pipeline(Get("http://169.254.169.254/latest/dynamic/instance-identity/document"))
于 2014-07-15T17:12:21.007 に答える