akka-http représente un fichier téléchargé en utilisant le codage multipart/form-data comme Source[ByteString, Any]
. Je dois le démarsaler en utilisant Java qui attend un InputStream
.
Comment Source[ByteString, Any]
peut être transformé en InputStream
?
À partir de la version 2.x, vous y arrivez avec le code suivant:
import akka.stream.scaladsl.StreamConverters
...
val inputStream: InputStream = entity.dataBytes
.runWith(
StreamConverters.asInputStream(FiniteDuration(3, TimeUnit.SECONDS))
)
Remarque: a été cassé dans la version 2.0.2 et corrigé dans 2.4.2
Vous pouvez essayer d'utiliser un OutputStreamSink
qui écrit dans un PipedOutputStream
et l'introduire dans un PipedInputStream
que votre autre code utilise comme flux d'entrée. C'est un peu approximatif mais ça pourrait marcher. Le code ressemblerait à ceci:
import akka.util.ByteString
import akka.stream.scaladsl.Source
import Java.io.PipedInputStream
import Java.io.PipedOutputStream
import akka.stream.io.OutputStreamSink
import Java.io.BufferedReader
import Java.io.InputStreamReader
import akka.actor.ActorSystem
import akka.stream.ActorFlowMaterializer
object PipedStream extends App{
implicit val system = ActorSystem("flowtest")
implicit val mater = ActorFlowMaterializer()
val lines = for(i <- 1 to 100) yield ByteString(s"This is line $i\n")
val source = Source(lines)
val pipedIn = new PipedInputStream()
val pipedOut = new PipedOutputStream(pipedIn)
val flow = source.to(OutputStreamSink(() => pipedOut))
flow.run()
val reader = new BufferedReader(new InputStreamReader(pipedIn))
var line:String = reader.readLine
while(line != null){
println(s"Reader received line: $line")
line = reader.readLine
}
}
Vous pouvez extraire un interator de ByteString puis obtenir InputStream. Quelque chose comme ça (pseudocode):
source.map { data: ByteString =>
data.iterator.asInputStream
}
Mise à jour
Un exemple plus élaboré commençant par un Multipart.FormData
def isSourceFromFormData(formData: Multipart.FormData): Source[InputStream, Any] =
formData.parts.map { part =>
part.entity.dataBytes
.map(_.iterator.asInputStream)
}.flatten(FlattenStrategy.concat)