本文将介绍使用multipart/form-data方式上传文件的方式和踩坑。

使用RestTemplate框架上传文件

调用postForObject接口上传文件,直接上代码

@Test
public void restTemplateTransferFile(){
    final String filePath = "picture/testFile.jpg"; //相对地址,也可以使用绝对地址
    final String fileName = "testFile";
    final String url = "http://localhost:8080/file/upload";

    RestTemplate restTemplate = new RestTemplate();

    //设置请求头
    HttpHeaders headers = new HttpHeaders();
    MediaType type = MediaType.parseMediaType("multipart/form-data");
    //设置传输方式为multipart/form-data
    headers.setContentType(type);
    
    FileSystemResource fileSystemResource = new FileSystemResource(filePath);
    //使用MultiValueMap保存表单对象,注意使用LinkedMultiValueMap实例化
    MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
    form.add("file", fileSystemResource);
    form.add("filename",fileName);

 	//用HttpEntity封装整个请求报文
    HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(form, headers);

    String s = restTemplate.postForObject(url, httpEntity, String.class);
    System.out.println(s);
}

主要步骤是:

  • 利用HttpHeader将请求头的设置为"multipart/form-data";
  • 利用FileSystemResource封装文件内容,将请求体用LinkedMultiValueMap封装;
FileSystemResource fileSystemResource = new FileSystemResource(filePath+"/"+fileName);

可以放完整路径,带文件名字

FileSystemResource fileSystemResource = new FileSystemResource("testPng/picture.jpg");

注意:

  • 这里是相对路径,文件目录放在服务器项目运行目录下(如/bin目录),运行时会自动把前面路径补全。
  • 不能用数字代替文件名。 (可能是被远程传输给坑了,图片的确是空的0kb)检查传输文件是否为空,会报错。
  1. 再用HttpEntity封装整个请求报文;
  2. 最后利用RestTemplate post请求。

使用HttpURLConnection 上传文件

见参考3、 Http multipart/form-data多参数Post方式上传数据
4、Http multipart/form-data多参数Post方式上传数据

报文件为空的问题

首先检查文件是否真的为空(0KB),笔者在远程传输图片文件之后,文件内容变成空的了,之前没意识到这个问题,走了很多弯路。

其次,重写ByteArrayResource类的getFilename()方法

ByteArrayResource byteArrayResource = new ByteArrayResource(file.getBytes());

重写getFilename()方法:

public Map<String,Object>  upload(@RequestParam("file") MultipartFile file) throws IOException {
    MultiValueMap<String, Object> bodyParams = new LinkedMultiValueMap<>();
    ByteArrayResource resource = new ByteArrayResource(file.getBytes()){
        @Override
    		public String getFilename() throws IllegalStateException {
        		return file.getOriginalFilename();
    		}
    };
    bodyParams.add("file", resource);
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(bodyParams, headers);
    Map<String,Object> map = template.postForObject("http://xxx/file/upload", requestEntity, Map.class);
    return map;
}

参考:
1、文件上传操作(MultipartFile 接口) 案例
2、使用MultipartFile 做文件上传的功能
3、Http multipart/form-data多参数Post方式上传数据
4、Http multipart/form-data多参数Post方式上传数据

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐