# Play File Upload using a custom BodyParser
[![Build Status](https://travis-ci.org/playframework/play-java-fileupload-example.svg?branch=2.6.x)](https://travis-ci.org/playframework/play-java-fileupload-example)
This is a sample project that shows how to upload a file through Akka Streams using a custom BodyParser using Akka Streams using the Java API.
## Default MultipartFormData Body Parser
Play's Java API specifies a BodyParser.MultipartFormData class which uses a TemporaryFile wrapper class that creates a file under a "temporary" name and then deletes it only when the system is under GC pressure.
```java
@BodyParser.Of(BodyParser.MultipartFormData.class)
public Result upload() throws IOException {
final Http.MultipartFormData<File> formData = request().body().asMultipartFormData();
final Http.MultipartFormData.FilePart<File> filePart = formData.getFile("name");
final File file = filePart.getFile();
final long data = operateOnTempFile(file);
return ok("file size = " + data + "");
}
```
## Customizing the Body Parser
There are cases where it's useful to have more control over where and Play uploads multi part form data. In this case, we'd like to get access to the accumulated byte stream for each file part and generate a file directly, without going through TemporaryFile.
In short, we want to replace:
```java
@BodyParser.Of(BodyParser.MultipartFormData.class)
```
with:
```java
@BodyParser.Of(MyMultipartFormDataBodyParser.class)
```
And we want to change as little code as possible. The underlying mechanics are simple. `MyMultipartFormDataBodyParser` does all the work of setting up a custom file part handler using a method called `createFilePartHandler`:
```java
class MyMultipartFormDataBodyParser extends DelegatingMultipartFormDataBodyParser<File> {
@Inject
public MyMultipartFormDataBodyParser(Materializer materializer, play.api.http.HttpConfiguration config) {
super(materializer, config.parser().maxDiskBuffer());
}
/**
* Creates a file part handler that uses a custom accumulator.
*/
@Override
public Function<Multipart.FileInfo, Accumulator<ByteString, Http.MultipartFormData.FilePart<File>>> createFilePartHandler() {
return (Multipart.FileInfo fileInfo) -> {
final String filename = fileInfo.fileName();
final String partname = fileInfo.partName();
final String contentType = fileInfo.contentType().getOrElse(null);
final File file = generateTempFile();
final Sink<ByteString, CompletionStage<IOResult>> sink = FileIO.toFile(file);
return Accumulator.fromSink(
sink.mapMaterializedValue(completionStage ->
completionStage.thenApplyAsync(results -> {
//noinspection unchecked
return new Http.MultipartFormData.FilePart(partname,
filename,
contentType,
file);
})
));
};
}
/**
* Generates a temp file directly without going through TemporaryFile.
*/
private File generateTempFile() {
try {
final Path path = Files.createTempFile("multipartBody", "tempFile");
return path.toFile();
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}
```
The core Accumulator is generated from an `akka.streams.FileIO` sink which writes out bytes to the filesystem, and exposes a CompletionStage when the write operation has been completed.
Because this code delegates to the Scala API implementation, the underlying `DelegatingMultipartFormDataBodyParser<A>` exposes an abstract method:
```java
abstract Function<Multipart.FileInfo, Accumulator<ByteString, Http.MultipartFormData.FilePart<A>>> createFilePartHandler();
```
`DelegatingMultipartFormDataBodyParser` does not know about any particular type, only `FilePart<A>`, and so it falls to the implementation to fill in the details.
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
play-java-fileupload-example.zip (35个子文件)
play-java-fileupload-example
sbt 44B
gradlew.bat 2KB
gradlew 5KB
conf
application.conf 67B
logback.xml 2KB
routes 448B
test
browsers
BrowserTest.java 960B
controllers
HomeControllerTest.java 2KB
sbt-dist
bin
sbt 5KB
sbt-launch-lib.bash 7KB
sbt-launch.jar 1.15MB
sbt.bat 1KB
conf
sbtopts 939B
sbtconfig.txt 147B
LICENSE 439B
app
controllers
HomeController.java 1KB
MyMultipartFormDataBodyParser.java 3KB
FormData.java 295B
views
main.scala.html 900B
index.scala.html 264B
gradle
wrapper
gradle-wrapper.jar 53KB
gradle-wrapper.properties 200B
build.sbt 255B
.gitignore 95B
project
plugins.sbt 449B
build.properties 18B
public
images
favicon.png 687B
javascripts
hello.js 89B
stylesheets
main.css 0B
README.md 4KB
scripts
test-gradle 507B
test-sbt 238B
script-helper 428B
sbt.bat 55B
build.gradle 990B
共 35 条
- 1
资源评论
刘良运
- 粉丝: 67
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功