### 1、文件上传

Solon 的文件上传对象由 UploadedFile 表示。属性有：


| 属性或方法 | 描述 | 
| -------- | -------- | 
| content             | 内容流                  | 
| ontentAsBytes   | 内容的 byte[] 形式  |
| contentType      | 内容类型     |
| contentSize       | 内容大小     | 
| name                | 文件名字（全名）     | 
| extension          | 扩展名字     | 
|      |      |   
|  delete()              |   删除临时文件方法   |   
|  isEmpty()            |   检查是否为空方法   |    
|  transferTo(File)    |  转换流到文件方法    |    



注意：

上传文件处理完后，用 `UploadedFile:delete` 主动删除掉“可能的”临时文件。v2.7.2 后支持

```java
public class DemoController{
    //文件上传 //表单变量名要跟参数名对上（如果名字对不上，要用 @Param 指定）
    @Post
    @Mapping("/upload1")
    public String upload(UploadedFile file, @Param("logo") UploadedFile img) { 
        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、文件上传相关配置参考

```yaml
#设定最大的请求包大小（或表单项的值大小）//默认: 2m
server.request.maxBodySize: 2mb #kb,mb
#设定最大的上传文件大小
server.request.maxFileSize: 2mb #kb,mb (默认使用 maxBodySize 配置值)
#设定最大的请求头大小//默认: 8k
server.request.maxHeaderSize: 8kb #kb,mb
#设定上传使用临时文件（v2.7.2 后支持。v3.6.0 后失效，由 fileSizeThreshold 替代）
server.request.useTempfile: false #默认 false
#设定上传文件大小阀值（v3.6.0 后支持）
server.request.fileSizeThreshold: 512kb #默认 512kb
```

关于临时文件（即，先缓存到磁盘）的支持情况（所有适配的 solon-server 都支持）：


| 插件 | 情况 | 
| -------- | -------- | 
| solon-server-jdkhttp     | 支持     | 
| solon-server-smarthttp     | 支持     | 
| solon-server-grizzly	| 支持
| solon-server-jetty     | 支持     | 
| solon-server-jetty-jakarta     | 支持     | 
| solon-server-undertow     | 支持    | 
| solon-server-undertow-jakarta     | 支持    | 




### 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）。即支持分片下载、播放。

```java
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` <br>`text/javascript,application/javascript` <br> `text/xml,application/xml`     |


注意：mimeTypes 默认的常见的类型，如果有需要“增量添加”即可

### 5、指定外部静态资源仓库（静态文件）

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

参考插件：[solon-web-staticfiles](/article/268)