九、上传下载及外部静态资源
1、文件上传
Solon 的文件上传对象由 UploadedFile 表示。属性有:
属性或方法 | 描述 |
---|---|
content | 内容流 |
ontentAsBytes | 内容的 byte[] 形式 |
contentType | 内容类型 |
contentSize | 内容大小 |
name | 文件名字(全名) |
extension | 扩展名字 |
delete() | 删除临时文件方法 |
isEmpty() | 检查是否为空方法 |
transferTo(File) | 转换流到文件方法 |
注意:
上传文件处理完后,用 UploadedFile:delete
主动删除掉“可能的”临时文件。v2.7.2 后支持
public class DemoController{
//文件上传
@Post
@Mapping("/upload1")
public String upload(UploadedFile file) { //表单变量名要跟参数名对上
try{
file.transferTo(new File("/demo/user/logo.jpg")); //把它转为本地文件
} finally {
//用完之后,删除"可能的"临时文件 //v2.7.2 后支持
file.delete();
}
return file.name;
}
//文件上传
@Post
@Mapping("/upload2")
public void upload(UploadedFile[] file) { //同名多文件 //v2.3.8 后支持
//file[0].transferTo(new File("/demo/user/logo.jpg")); //把它转为本地文件
}
//通过 multipart 提交的数据,且不带 UploadedFile 参数;须加 multipart 申明
@Post
@Mapping(path="/upload3", multipart=true)
public String upload(String user) {
return user;
}
//通过 multipart 提交的数据,且不带 UploadedFile 参数;须加 multipart 申明
@Post
@Mapping(path="/upload4", multipart=true)
public String upload(String user, Context ctx) {
UploadedFile file = ctx.file("file"); //UploadedFile[] file= ctx.files("file"); 同名多文件
return file.name;
}
}
关于文件上传的内存情况:
方案 | 适合场景 | 备注 |
---|---|---|
1、先缓存到磁盘,然后给出本地文件流 | 适合大文件、低频 | 高频了,磁盘可能吃不消(注意临时文件的清理) |
2、直接在内存里操作 | 适合小文件、高频 | 文件大了,容易占用内存 |
2、文件上传相关配置参考
#设定最大的请求包大小(或表单项的值大小)//默认: 2m
server.request.maxBodySize: 2mb #kb,mb
#设定最大的上传文件大小
server.request.maxFileSize: 2mb #kb,mb (默认使用 maxBodySize 配置值)
#设定最大的请求头大小//默认: 8k
server.request.maxHeaderSize: 8kb #kb,mb
#设定上传使用临时文件(v2.7.2 后支持)
server.request.useTempfile: false //默认 false
关于 useTempfile (即,先缓存到磁盘)的配置支持(v2.7.2 后支持):
插件 | 情况 |
---|---|
solon-boot-jdkhttp | 支持 |
solon-boot-jlhttp | 支持 |
solon-boot-smarthttp | 支持 |
solon-boot-jetty | 支持 |
solon-boot-undertow | 不支持(强制使用临时文件模式) |
3、文件下载输出(支持 gzip 配置)
Solon 的文件下载处理由 DownloadedFile 表示(也可以是 File 或者自己处理流输出)。DownloadedFile 属性有:
属性或方法 | 描述 | 默认值 |
---|---|---|
content | 内容流 | |
contentType | 内容类型 | |
contentSize | 内容大小 | |
name | 文件名字(全名) | |
asAttachment(bool) | 做为附件输出(浏览器会自动下载) | true |
cacheControl(int) | 304 缓存动态控制(单位:秒) | 0 |
eTag(String) | eTag |
使用 DownloadedFile 或 File 时,支持 http 分片协议(Http-Range)。即支持分片下载、播放。
public class DemoController{
//文件下载
@Get
@Mapping("/down")
public DownloadedFile down() {
//输出的文件名,可以自己指定
byte[] bytes = "{\"code\":1}".getBytes(StandardCharsets.UTF_8);
return new DownloadedFile("text/json", bytes, "test.json");
}
//文件下载
@Get
@Mapping("/down2")
public File down2() {
//输出的文件名,为 File 的文件名
return new File("/demo/user/logo.jpg");
}
//文件下载
@Get
@Mapping("/down2_2")
public void down2_2(Context ctx) {
//输出的文件名,为 File 的文件名
File file = new File("/demo/user/logo.jpg");
ctx.outputAsFile(file);
}
//文件下载
@Get
@Mapping("/down3")
public DownloadedFile down3() {
//简化写法
DownloadedFile file = new DownloadedFile(new File("/demo/user/logo.jpg"));
//不做为附件下载(按需配置)
file.asAttachment(false);
//支持前端缓存控制
file.cacheControl(60*60);
file.eTag("demo-tag");
return file;
}
//文件下载
@Get
@Mapping("/down3_2")
public void down3_2(Context ctx) {
//输出的文件名,可以自己指定
DownloadedFile file = new DownloadedFile(new File("/demo/user/logo.jpg"), "logo-new.jpg");
//不做为附件下载(按需配置)
//file.asAttachment(false);
//也可用接口输出
ctx.outputAsFile(file);
}
}
4、文件下载相关配置
配置 | 描述 | 默认值 |
---|---|---|
server.http.gzip.enable | 是否启用 | false |
server.http.gzip.minSize | 最小的文件大小 | 4096 |
server.http.gzip.mimeTypes | 内容类型(增量添加) | text/html,text/plain,text/css text/javascript,application/javascript text/xml,application/xml |
注意:mimeTypes 默认的常见的类型,如果有需要“增量添加”即可
5、指定外部静态资源仓库
比如,把上传的文件放到 /demo/user/
,同时把它做为静态资源仓库