Solon

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

</> markdown

1、文件上传

注意:上传文件处理完后,用 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、文件下载输出

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() {
        //输出的文件名,可以自己指定
        InputStream stream = new FileInputStream(new File("/demo/user/logo.jpg"))
        DownloadedFile file = new DownloadedFile("image/jpg", stream, "logo-new.jpg");
        
        //不做为附件下载(按需配置)
        //file.asAttachment(false);
        
        return file;
    }
    
    //文件下载
    @Get
    @Mapping("/down3_2")
    public void down3_2(Context ctx) {
        //简化写法
        DownloadedFile file = new DownloadedFile(new File("/demo/user/logo.jpg"));
        
        //不做为附件下载(按需配置)
        file.asAttachment(false);
        
        ctx.outputAsFile(file);
    }
}    

4、指定外部静态资源仓库

比如,把上传的文件放到 /demo/user/,同时把它做为静态资源仓库

参考插件:solon.web.staticfiles