Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Using custom multipart body parser that uses specified dir to save files
package controllers;
import java.util.List;
import play.mvc.BodyParser;
import play.mvc.BodyParser.Of;
import play.mvc.Controller;
import play.mvc.Http.MultipartFormData;
import play.mvc.Http.MultipartFormData.FilePart;
import play.mvc.Http.RequestBody;
import play.mvc.Result;
import utils.CustomParsers;
import views.html.index;
public class Application extends Controller {
public static class PermanentMultipartFormData implements BodyParser {
//location to save the files
private final File dir = new File("data");
public play.api.mvc.BodyParser<RequestBody> parser(int maxLength) {
return CustomParsers.permanentMultipartFormData(dir, maxLength);
public static Result upload() {
MultipartFormData md = request().body().asMultipartFormData();
//do your thing
public static Result index() {
return ok(index.render("Your new application is ready."));
package utils
import play.api.mvc._
import play.mvc.Http.RequestBody
import play.api.mvc.BodyParsers._
import parse._
import play.core.j.JavaParsers.DefaultRequestBody
import play.api.libs.iteratee.Iteratee
import play.api.mvc.MultipartFormData._
import play.api.libs.Files.TemporaryFile
import scala.collection.JavaConverters._
object CustomParsers {
case class MultipartRequestBody(multipart: MultipartFormData[File]) extends RequestBody {
override lazy val asMultipartFormData = {
new play.mvc.Http.MultipartFormData {
lazy val asFormUrlEncoded = {
lazy val getFiles = { { file =>
new play.mvc.Http.MultipartFormData.FilePart(
file.key, file.filename, file.contentType.orNull, file.ref)
private def orDefault(maxLength: Int) = if (maxLength < 0) parse.DEFAULT_MAX_TEXT_LENGTH else maxLength
type PartHandler[A] = PartialFunction[Map[String, String], Iteratee[Array[Byte], A]]
def permanentMultipartFormData(dir: File, maxLength: Int): BodyParser[RequestBody] = {
parse.maxLength(orDefault(maxLength), parse.multipartFormData(handleFilePartAsPermanentFile(dir))).map {
_ => DefaultRequestBody(isMaxSizeExceeded = true),
multipart =>
def handleFilePartAsPermanentFile(dir: File): PartHandler[FilePart[File]] = {
Multipart.handleFilePart {
case Multipart.FileInfo(partName, filename, contentType) =>
val file = new File(dir, filename)
Iteratee.fold[Array[Byte], FileOutputStream](new { (os, data) =>
}.map { os =>


Thank you very much for sharing this code, as I have a very similar need.

At the same time, our http end point is currently overloaded to handle different content-types, either multipart of urlencoded content-types.

Is there any way, I can get hold of the Content-Type, in the PermanentMultipartFormData.parser method, so that I can return different parsers depending on content type.

I see that BodyParsers.parse.anyContent is being passed a request object, but I am not sure how to access that in the mentioned method. The Threadlocal Http Context itself seems uninitialized at this point of time.

Please let me know. I can live with single parser option too, where during parsing it can figure out what content -type it is going to be.

Satish Vemula

msegeya commented Jul 24, 2015

adding the import below to the scala code


Fixed some errors that i faced while using this code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment