2017-10-24 8 views
0

는 엑셀 시트를 업로드하고 로컬에 저장하기위한 서버 측에서akka HTTP에서 엑셀 파일을 업로드하는 방법 마이크로 서비스

def uploadFile(fileData: Multipart.FormData) = { 
println(" uploadFile ") 
// path("user"/"upload"/"file") { 
/* (post & entity(as[Multipart.FormData])) { fileData =>*/ 
complete { 
    val fileName = UUID.randomUUID().toString 
    val temp = System.getProperty("java.io.tmpdir") 
    val filePath = temp + "/" + fileName+".xls" 
    // var filePath = current.configuration.getString("upload.file.path").get + "/" + fileName 
    println(fileData.getParts() + " - " + fileData.getMediaType() + " filePath " + filePath + " fileName " + fileName) 
    val processingFileUpload = processFile(filePath, fileData) 
    /*val poResult = Await.result(processingFileUpload, 50 seconds) 
    println(" processFile " + poResult)*/ 
    processingFileUpload.map { fileSize => 
    HttpResponse(StatusCodes.OK, entity = s"File successfully uploaded. Fil size is $fileSize") 
    }.recover { 
    case ex: Exception => HttpResponse(StatusCodes.InternalServerError, entity = "Error in file uploading") 
    } 
    // } 
    // } 
} 
} 

을 Akka의 HTTP를 사용하고 내에는 processFile는

private def processFile(filePath: String, fileData: Multipart.FormData) = { 
    val fileOutput = new FileOutputStream(filePath) 
    println(" fileOutput " + fileOutput+" fileDatas "+fileData.parts.module) 
// fileData.parts.mapAsync(1) { bodyPart => 
    fileData.parts.mapAsyncUnordered(1) { bodyPart => 
    println(" bodyPartLog " + bodyPart) 
    def writeFileOnLocal(array: Array[Byte], byteString: ByteString): Array[Byte] = { 
     println(" arraysdss " + array) 
     val byteArray: Array[Byte] = byteString.toArray 
     fileOutput.write(byteArray) 
     println(" sdssasx " + byteArray) 
     array ++ byteArray 
    } 
    bodyPart.entity.dataBytes.runFold(Array[Byte]())(writeFileOnLocal) 
    }.runFold(0)(_ + _.length) 
} 

입니다 나는 매번 mapAsync와 mapAsyncUnordered를 모두 얻었습니다. 파일을 업로드 할 때 오류가 발생했습니다. 예외가 발생하여 직접 서버에 데이터를 쓸 수 있습니다.

+0

예외가 무엇인지 추측 할 수 있습니까? 가장 많이 사용하는 processFile 구현을 다음과 같이 바꾸고 싶을 것입니다 : https://doc.akka.io/api/akka/current/akka/stream/scaladsl/FileIO$.html 구현시 현재 출력을 닫지 않고 전체 내용을 메모리로 읽어 들이고 데이터의 여러 복사본을 만드는 등의 문제 –

답변

0

파일 업로드에 다른 방법을 사용했는데 작동 중입니다

(post & entity(as[Multipart.FormData])) { request => 
    extractRequestContext { 
    ctx => { 
     implicit val materializer = ctx.materializer 
     implicit val ec = ctx.executionContext 
     fileUpload("fileUpload") { 
     case (fileInfo, fileStream) => 

      val localPath = "c:\\test" 
      val sink = FileIO.toPath(Paths.get(localPath) resolve fileInfo.fileName) 
      val writeResult = fileStream.runWith(sink) 
      onSuccess(writeResult) { result => 
      result.status match { 
       case Success(_) => complete(s"Successfully written ${result.count} bytes") 
       case Failure(e) => throw e 
      } 
      } 
     } 
    } 
    } 
}