如果注入请求参数时，总是尝试Multipart解析（根据上下文类型识别）；并且，如果有人恶意通过Multipart上传一个超大文件。服务进程的内存可能会激增。



### 1、两种处理策略

如果不触发解析，则不会占用内存。故采用两种策略，“便利”且“按需”处理。

* 自动处理（当 Action 有 UploadedFile 参数时；自动进行解析）
* 显示声明


```java
@Controller
public class DemoController{
    //文件上传
    @Post
    @Mapping("/upload")
    public String upload(UploadedFile file) {
        return file.name;
    }
    
    //通过 multipart 提交的数据，且不带 UploadedFile 参数；须加 multipart 声明
    @Post
    @Mapping(path="/upload1", multipart=true)
    public String upload(String user) {
        return user;
    }
}    
```

当 ctx.autoMultipart() = true 是（出于便利考虑，默认为 true），会自动解析。出于安全考虑，最好关掉自动处理或者通过路径特径进行控制。(关掉自动处理后，获取 multipart 数据参考上面的做法)

```java
public class DemoApp {
    public static void main(String[] args) {
        Solon.start(DemoApp.class, args, app -> {
            app.filter(-1, (ctx, chain) -> {
                if(ctx.path().contains("/upload")) {
                    //只给需要的路径加 autoMultipart = true
                    ctx.autoMultipart(true); 
                }else{
                    ctx.autoMultipart(false);  
                }

                chain.doFilter(ctx);
            });
        });
    }
}
```

最好再限制一下上传文件大小 

```yml#
设定最大的上传文件大小
server.request.maxFileSize: 20mb #kb,mb (默认使用 maxBodySize 配置值)
```

如果文件很大，可以使用临时文件模式节省内存

```yaml
#设定上传使用临时文件（v2.7.2 后支持。v3.6.0 后失效，由 fileSizeThreshold 替代）
server.request.useTempfile: false #默认 false

#设定上传文件大小阀值（v3.6.0 后支持）
server.request.fileSizeThreshold: 512kb #默认 512kb
```

### 2、顺带，也放一下文件下载的示例：

```java
public class DemoController{
    @Mapping("down/f1")
    public DownloadedFile down() {
        InputStream stream = new ByteArrayInputStream("{code:1}".getBytes(StandardCharsets.UTF_8));

        //使用 InputStream 实例化
        return new DownloadedFile("text/json", stream, "test.json");
    }

    @Mapping("down/f2")
    public DownloadedFile down12() {
        byte[] bytes = "test".getBytes(StandardCharsets.UTF_8);

        //使用 byte[] 实例化
        return new DownloadedFile("text/json", bytes, "test.txt");

    }

    @Mapping("down/f3")
    public File down2() {
        return new File("...");
    }

    @Mapping("down/f4")
    public void down3(Context ctx) throws IOException {
        File file = new File("...");

        ctx.outputAsFile(file);
    }
}    
```

