Search code examples
excelscalaakkaakka-streamakka-http

how to upload the excel file in akka http micro services


am using Akka HTTP in server side for uploading the excel sheet and saving into the local,

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")
  }
  //  }
  // }
}
 }

and my processFile is

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)
}

i have traied both mapAsync and mapAsyncUnordered am getting the every time Error in file uploading it's directly jumped into the exception how can write the the data into my server local through uploading the service


Solution

  • I have used another method for file uploading and it's working too

    (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
                }
              }
          }
        }
      }
    }