Skip to content
Create a gist now

Instantly share code, notes, and snippets.

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
Something went wrong with that request. Please try again.