有人可以帮助我掌握喷码以更好地了解如何喷涂吗? 我是将文件作为多部分数据发送的上下文。
向我建议的代码是:
import akka.actor.ActorSystem
import spray.client.pipelining._
import spray.http.{MediaTypes, BodyPart, MultipartFormData}
object UploadFileExample extends App {
implicit val system = ActorSystem("simple-spray-client")
import system.dispatcher // execution context for futures below
val pipeline = sendReceive
val payload = MultipartFormData(Seq(BodyPart(new File("/tmp/test.pdf"), "datafile", MediaTypes.`application/pdf`)))
val request =
Post("http://localhost:8080/file-upload", payload)
pipeline(request).onComplete { res =>
println(res)
system.shutdown()
}
}
哪个好,当然有效。
但是,我想了解引擎盖下的内容,以便我可以自己做事:
以下是来自此代码的混淆:
BodyPart(new File("/tmp/test.pdf"), "datafile", MediaTypes.`application/pdf`)
是第一个问题,实际上,BodyPart只有一个紧密匹配的apply方法:
def apply(file: File, fieldName: String, contentType: ContentType): BodyPart =
apply(HttpEntity(contentType, HttpData(file)), fieldName, Map.empty.updated("filename", file.getName))
它采用contentType而不是MediaType。
但我在contentType
中找到了object ContentType {
private[http] case object `; charset=` extends SingletonValueRenderable
def apply(mediaType: MediaType, charset: HttpCharset): ContentType = apply(mediaType, Some(chars et))
implicit def apply(mediaType: MediaType): ContentType = apply(mediaType, None) }
但是ContentType不在Main的范围内(参见顶部的第一个代码。)因此我不知道隐式转换的来源是什么?
然后我在这里不明白的最后一件事是
val payload = MultipartFormData(Seq(BodyPart(new File("/tmp/test.pdf"),
"datafile", MediaTypes.`application/pdf`)))
Post("http://localhost:8080/file-upload", payload)
这里的问题是,它基于RequestBuilding(可以在RequestBuilding Source中找到)
val Post = new RequestBuilder(POST)
包含一个包含apply方法的对象:
def apply[T: Marshaller](uri: String, content: Option[T]): HttpRequest = apply(Uri(uri), content)
....
....
def apply[T: Marshaller](uri: Uri, content: Option[T]): HttpRequest = {
val ctx = new CollectingMarshallingContext {
override def startChunkedMessage(entity: HttpEntity, ack: Option[Any],
headers: Seq[HttpHeader])(implicit sender: ActorRef) =
sys.error("RequestBuilding with marshallers producing chunked requests is not supported")
}
content match {
case None ⇒ HttpRequest(method, uri)
case Some(value) ⇒ marshalToEntityAndHeaders(value, ctx) match {
case Right((entity, headers)) ⇒ HttpRequest(method, uri, headers.toList, entity)
case Left(error) ⇒ throw error
}
}
}
MultiPartFormData不是Marshaler,因此我不明白它是如何工作的。
有人可以帮我解决这个问题吗?
非常感谢,
中号