# 文件上传

- SDK

详细代码可参考sdk-java模块代码，位于单元测试文件中

```java
/**
     * 上传文件，读取本地文件
     *
     * @throws IOException
     */
    @Test
    public void testUpload() throws IOException {
        FileUploadRequest request = new FileUploadRequest();

        GoodsParam param = new GoodsParam();
        param.setGoods_name("iphone6");
        request.setParam(param);

        List<UploadFile> files = new ArrayList<>();
        String path = this.getClass().getResource("").getPath();
        files.add(new UploadFile("headImg", new File(path + "BaseTest.class")));
        files.add(new UploadFile("idcardImg", new File(path + "SdkTest.class")));
        request.setFiles(files);

        FileUploadResponse response = client.execute(request);

        System.out.println("--------------------");
        if (response.isSuccess()) {
            String data = response.getData();
            System.out.println(data);
        } else {
            System.out.println("errorCode:" + response.getCode() + ",errorMsg:" + response.getMsg());
        }
        System.out.println("--------------------");
    }
```

- 服务端处理

```java
@ApiService
@ApiDoc("文件上传")
public class UploadFileApi {

    /**
     * 方式1
     * @param param
     * @return
     * @throws IllegalStateException
     * @throws IOException
     */
    @Api(name = "file.upload")
    @ApiDocMethod(description = "文件上传")
    Object upload(UploadParam param) throws IllegalStateException, IOException {
        // 获取上传文件
        MultipartFile headImgFile = param.getHeadImg();
        MultipartFile idcardImgFile = param.getIdcardImg();

        StringBuilder sb = new StringBuilder();
        sb.append("表单名：").append(headImgFile.getName()).append(",")
        .append("文件大小：").append(headImgFile.getSize()).append(";");
        
        sb.append("表单名：").append(idcardImgFile.getName()).append(",")
        .append("文件大小：").append(idcardImgFile.getSize()).append(";");
        
        // headImgFile.getInputStream(); // 返回文件流
        // headImgFile.getBytes(); // 返回文件数据流
        
        headImgFile.transferTo(new File("D:/new_" + headImgFile.getOriginalFilename()));
        idcardImgFile.transferTo(new File("D:/new_" + idcardImgFile.getOriginalFilename()));

        return new ApiResult(sb.toString());
    }
    
    /**
     * 方式2
     * 
     * @param param
     * @return
     * @throws IllegalStateException
     * @throws IOException
     */
    @Api(name = "file.upload2")
    Object upload2(GoodsParam param) throws IllegalStateException, IOException {
        // 获取上传文件上下文
        UploadContext uploadContext = ApiContext.getUploadContext();
        // 返回所有的上传文件
        List<MultipartFile> files = uploadContext.getAllFile();
        
        StringBuilder sb = new StringBuilder();
        
        for (MultipartFile multipartFile : files) {
            sb
            .append("表单名：").append(multipartFile.getName()).append(",")
            .append("文件大小：").append(multipartFile.getSize()).append(";")
            ;
            // multipartFile.getInputStream(); // 返回文件流
            // multipartFile.getBytes(); // 返回文件数据流
            // 写文件到本地
            multipartFile.transferTo(new File("D:/new2_" + multipartFile.getOriginalFilename()));
        }
        
        return new ApiResult(sb.toString());
    }
    
    @Api(name = "file.upload3")
    @ApiDocMethod(description = "文件上传,不确定数量")
    Object upload(UploadParam2 param) throws IllegalStateException, IOException {
        // 获取上传文件
        List<MultipartFile> files = param.getFiles();
        
        StringBuilder sb = new StringBuilder();
        
        for (MultipartFile multipartFile : files) {
            sb
            .append("表单名：").append(multipartFile.getName()).append(",")
            .append("文件名：").append(multipartFile.getOriginalFilename()).append(",")
            .append("文件大小：").append(multipartFile.getSize()).append(";")
            ;
            
            multipartFile.transferTo(new File("D:/new2_" + multipartFile.getOriginalFilename()));
            
        }
        
        return new ApiResult(sb.toString());
    }
}
```

- UploadParam.java

```java
public class UploadParam {

    @ApiDocField(description = "商品名称", required = true, example = "iphoneX")
    @NotEmpty(message = "商品名称不能为空")
    @Length(min = 3, max = 20, message = "{goods.name.length}=3,20")
    private String goods_name;

    // 这里定义上传的文件，属性名称对应客户端上传的name
    @ApiDocField(description = "头像图片", required = true, dataType = DataType.FILE)
    @NotNull(message = "请上传头像图片")
    private MultipartFile headImg;

    @ApiDocField(description = "身份证图片", required = true, dataType = DataType.FILE)
    @NotNull(message = "请上传身份证图片")
    private MultipartFile idcardImg;

    //getter,setter

}
```

- UploadParam2.java

```java
public class UploadParam2 {

    @Size(max = 2, message = "最多只能上传2个文件")
    @NotNull(message = "至少上传一个文件")
    @ApiDocField(description = "上传文件", elementClass = MultipartFile.class)
    private List<MultipartFile> files;

    public List<MultipartFile> getFiles() {
        return files;
    }

    public void setFiles(List<MultipartFile> files) {
        this.files = files;
    }

}
```

`headImg`,`idcardImg`就是上传的表单名，客户端需要于此对应。

## 上传内存文件

有些文件不是从本地读取的，而是从其它地方下载到内存中，比如从阿里云下载文件到内存中，不落地。

主要通过UploadFile类的构造方法来区分

```java
/**
 * @param name 表单名称，不能重复
 * @param file 文件
 * @throws IOException
 */
public UploadFile(String name, File file)

/**
 * @param name 表单名称，不能重复
 * @param fileName 文件名
 * @param input 文件流
 * @throws IOException
 */
public UploadFile(String name, String fileName, InputStream input)

/**
 * @param name 表单名称，不能重复
 * @param fileName 文件名
 * @param fileData 文件数据
 */
public UploadFile(String name, String fileName, byte[] fileData)
```

