Reputation:
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
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