2015-12-16 24 views
5

私は体内のJSONで応答するレガシーHTTP APIを使っていますが、Content-Type: text/plain; charset=utf-8ヘッダーを付けています。AkkaのHTTPでJSONとして `text/plain`をアンマーシャリングする方法

私はJSONとしてそのHTTPボディをアンマーシャリングしようとしていますが、私は次の例外を取得:akka.http.scaladsl.unmarshalling.Unmarshaller$UnsupportedContentTypeException: Unsupported Content-Type, supported: application/json

私のコードは次のようになります。

import spray.json.DefaultJsonProtocol 
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ 
import akka.http.scaladsl.unmarshalling._ 

case class ResponseBody(status: String, error_msg: String) 

object ResponseBodyJsonProtocol extends DefaultJsonProtocol { 
    implicit val responseBodyFormat = jsonFormat2(ResponseBody) 
} 

def parse(entity: HttpEntity): Future[ResponseBody] = { 
    implicit val materializer: Materializer = ActorMaterializer() 
    import ResponseBodyJsonProtocol._ 
    Unmarshal[HttpEntity](entity).to[ResponseBody] 
} 

サンプルHTTPレスポンスは次のようになります。

HTTP/1.1 200 OK 
Cache-Control: private 
Content-Encoding: gzip 
Content-Length: 161 
Content-Type: text/plain; charset=utf-8 
Date: Wed, 16 Dec 2015 18:15:14 GMT 
Server: Microsoft-IIS/7.5 
Vary: Accept-Encoding 
X-AspNet-Version: 4.0.30319 
X-Powered-By: ASP.NET 

{"status":"1","error_msg":"Missing parameter"} 

Content-TypeをHTTP応答で無視し、JSONとして解析するにはどうすればよいですか?

答えて

6

私はちょうどそれを手動でアンマーシャリングする前にHttpEntityContent-Typeを設定することがわかった一つの回避策:

def parse(entity: HttpEntity): Future[ResponseBody] = { 
    implicit val materializer: Materializer = ActorMaterializer() 
    import ResponseBodyJsonProtocol._ 
    Unmarshal[HttpEntity](entity.withContentType(ContentTypes.`application/json`)).to[ResponseBody] 
} 

はOK動作しているようですが、私は他のアイデアを開いている...

+0

私は同様の問題があり、アンマーシャリングの最後のコード行を使用しました。なんらかの理由で、withContentTypeはエンティティを変更し、コンテンツタイプオブジェクトも含む厳密なエンティティに変換します。それから体を引き出す方法に関するアイデアは? –

2

私は'map...ディレクティブを使用してください。短くてエレガントに見えます。

val routes = (decodeRequest & encodeResponse) { 
    mapResponseEntity(_.withContentType(ContentTypes.`application/json`)) { 
    nakedRoutes ~ authenticatedRoutes 
    } 
} 
+0

私はこれが当てはまるかどうかはわかりません....私の場合はルーティングが行われていないので、これが私の答えよりもどのように短くてエレガントであるかは確かに分かりません。しかし、同じアイデア。 –

+1

ああ、Spray DSLを使用しない場合は適用されません。 – expert

関連する問題