Solon v3.0.3

九、上传下载及外部静态资源

</> markdown

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/,同时把它做为静态资源仓库

参考插件:solon-web-staticfiles