user8574635
user8574635

Reputation:

Getting filename only from Scala/ Play

With Scala/Play I am working with uploading files.

With my scala.html, I have

@helper.form(action = routes.HomeController.uploadFile,
    'enctype -> "multipart/form-data") {
    <input type = "file" name = "picture">
    <p>
        <input type="submit">
    </p>
}

to upload files and directs to the controller which has,

 import org.apache.commons.io.FilenameUtils
import javax.inject._
import play.api._
import play.api.mvc._
import play.api.i18n.Messages.Implicits._
import play.api.Play.current
import play.api.data.Forms._
import play.api.data.Form
import models.MemberService




 def uploadFile = Action(parse.multipartFormData) { request =>
    request.body.file("picture").map { picture =>
      import java.io.File

      val filename = FileNameUtils.getName(picture.filename)
      picture.ref.moveTo(new File(s"/tmp/$filename"))
      Ok("upload completed")
    }.getOrElse {
      Redirect(routes.HomeController.index).flashing("error" -> "nofile exist")
    }
  }

and I am getting InvalidPathException error.

[InvalidPathException: Illegal char <:> at index 6: \tmp\C:\Users\jungj\Downloads\play-scala-starter-example.zip]

build.sbt

Here is my build.sbt

name := """play-scala"""
version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.7"

libraryDependencies ++= Seq(
  jdbc,
  cache,
  ws,
  "commons-io" % "commons-io" % "2.6",
  "com.typesafe.play" %% "anorm" % "2.5.0",
  "mysql" % "mysql-connector-java" % "5.1.34",
  "org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test


)

resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"

fork in run := true

I guess my val filename has the full name including the path and it causes this. I probably have to drop the directory and get name of the file only and put into val filename in order to moveTo correct path. I am pretty new to scala/play and want some detailed explanations. Can anyone help?

Upvotes: 1

Views: 405

Answers (1)

sarveshseri
sarveshseri

Reputation: 13985

The filename which you get by picture.filename describes the actual path of the uploaded file on the user's computer.

In this case it looks like the user was using a windows machine, and the actual path of file was C:\Users\jungj\Downloads\play-scala-starter-example.zip.

So, the value of /tmp/$filename will be /tmp/C:\Users\jungj\Downloads\play-scala-starter-example.zip which will be a totally invalid path.

So, what you actually need is a way to reliably extract actual filename from the foreign path in user's computer.

You can use org.apache.commons.io.FilenameUtils for this,

Add commons.io as dependency (in your build.sbt),

libraryDependencies += "commons-io" % "commons-io" % "2.6"

Now you can extract filename as follows,

import org.apache.commons.io.FilenameUtils

val filename = FilenameUtils.getName(picture.filename)

Upvotes: 0

Related Questions