2015-06-15 12 views
11

Tôi đang cố gắng để unmarshall yêu cầu tải trọng như chuỗi, nhưng đối với một số lý do nó không. Mã của tôi:Làm thế nào để unmarshall thực thể yêu cầu akka http như chuỗi?

path("mypath") { 

    post { 
    decodeRequest { 
     entity(as[String]) {jsonStr => //could not find implicit value for...FromRequestUnmarshaller[String] 
     complete { 
      val json: JsObject = Json.parse(jsonStr).as[JsObject] 
      val jsObjectFuture: Future[JsObject] = MyDatabase.addListItem(json) 
      jsObjectFuture.map(_.as[String]) 
     } 
     }   
    } 
    } 
} 

Trong ví dụ SO thread này có vẻ như ngầm định này sẽ có sẵn theo mặc định. Nhưng có lẽ điều này khác với akka-http?

Tôi đã thử nhập akka.http.scaladsl.unmarshalling.PredefinedFromEntityUnmarshallers có số stringUnmarshaller nhưng không hiệu quả. Có thể vì điều này trả về loại FromEntityUnmarshaller[String] không phải FromRequestUnmarshaller[String]. Ngoài ra còn có một chuỗi unmarshaller trong spray.httpx.unmarshalling.BasicUnmarshallers nhưng điều này cũng không được, không phải akka.http.scaladsl.unmarshalling.PredefinedFromStringUnmarshallers

Làm thế nào tôi có thể unmarshall (và marshall) thành một chuỗi?

(Tiền thưởng: Cách hủy tự động trực tiếp trong JsObject (phát json). Nhưng cũng chỉ chuỗi khi tôi quan tâm đến lý do tại sao tính năng này không hoạt động và có thể hữu ích cho các trường hợp khác).

Sử dụng 1.0-RC3

Cảm ơn.

Trả lời

15

Mã của bạn sẽ được chấp thuận miễn là bạn có quyền liên quan đến phạm vi. Nếu bạn có một tiềm ẩn FlowMaterializer trong phạm vi sau đó mọi chuyện nên làm việc như mong đợi như mã này để biên dịch chương trình:

import akka.http.scaladsl.server.Route 
import akka.actor.ActorSystem 
import akka.stream.ActorFlowMaterializer 
import akka.http.scaladsl.model.StatusCodes._ 
import akka.http.scaladsl.server.Directives._ 
import akka.stream.FlowMaterializer 

implicit val system = ActorSystem("test") 
implicit val mater = ActorFlowMaterializer() 

val routes:Route = { 
    post{ 
    decodeRequest{ 
     entity(as[String]){ str => 
     complete(OK, str) 
     } 
    } 
    }  
} 

Nếu bạn muốn để có những điều một bước xa hơn và unmarshall đến một JsObject sau đó bạn chỉ cần một tiềm ẩn Unmarshaller trong phạm vi để xử lý chuyển đổi đó, như sau:

implicit val system = ActorSystem("test") 
implicit val mater = ActorFlowMaterializer() 

import akka.http.scaladsl.unmarshalling.Unmarshaller 
import akka.http.scaladsl.model.HttpEntity 

implicit val um:Unmarshaller[HttpEntity, JsObject] = { 
    Unmarshaller.byteStringUnmarshaller.mapWithCharset { (data, charset) => 
    Json.parse(data.toArray).as[JsObject] 
    }  
} 

val routes:Route = { 
    post{ 
    decodeRequest{ 
     entity(as[String]){ str => 
     complete(OK, str) 
     } 
    } 
    } ~ 
    (post & path("/foo/baz") & entity(as[JsObject])){ baz => 
    complete(OK, baz.toString) 
    }  
} 
+0

Cảm ơn! Vấn đề của tôi là tôi tuyên bố ActorFlowMaterializer ẩn bên dưới định nghĩa các tuyến đường ... nó khá khó để phát hiện ra rằng đây là lý do cho phần marshalling không biên dịch, cho một newbie như tôi chỉ là không thể ... – Ixx

+0

Bên cạnh đó tôi phải có bỏ qua mệnh lệnh đó là rất quan trọng khi tuyên bố những lời buộc tội, hay cái gì đó khác, bởi vì các biến nằm trong phạm vi - ngay bên dưới các tuyến đường. – Ixx

+0

Cảm ơn cũng cho json unmarshaller, tôi thực sự sử dụng chuỗi, không phải byteString (đây chỉ là một thử nghiệm), nhưng có thể điều chỉnh nó một cách dễ dàng để làm việc với chuỗi. – Ixx

Các vấn đề liên quan