方案一:一句话总结,将前端传入的MultipartFile文件转为字节流发送到其他服务。
可以用RestTemplate也可以用HttpClient,以下是两种方法的说明。
用RestTemplate做
1.如果用RestTemplate的话首先需要把RestTemplate交给spring去管理所以先来一个配置类。
@Configuration @SuppressWarnings("all") public class RestTemplateConfig { @Autowired RestTemplateBuilder builder; @Bean public RestTemplate restTemplate() { return builder.build(); } }
2.RestTemplate远程调用文件传输
这里有几个要注意的地方
1.必须重写否则传输时报错
ByteArrayResource byteArrayResource = new ByteArrayResource(file.getBytes()) { @Override public String getFilename() { return file.getOriginalFilename(); } };
2.设置请求头因为就在模拟前端发送上传文件的请求所以请求头必须是multipart/form-data
代码:
@Autowired private RestTemplate restTemplate; private String gettestRestTemplate(MultipartFile file, String url) throws IOException { HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("multipart/form-data"); headers.setContentType(type); MultiValueMap<String, Object> form = new LinkedMultiValueMap<>(); ByteArrayResource byteArrayResource = new ByteArrayResource(file.getBytes()) { @Override public String getFilename() { return file.getOriginalFilename(); } }; form.add("file", byteArrayResource); form.add("filename", file.getOriginalFilename()); //用HttpEntity封装整个请求报文 HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(form, headers); String flag = restTemplate.postForObject(url, files, String.class); return flag; }
用HttpClient做
1.使用httpclient的话首先要引入pom文件坐标。
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.6</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.5.6</version> </dependency>
3.HttpClient远程调用文件传输
1.httpclient这段代码有要用的小伙伴直接粘过去就能用
注意一下返回值自己改一下就行execute.getEntity()
@SneakyThrows private String gettesthttpclient(MultipartFile file, String url) { CloseableHttpClient httpclient = HttpClients.createDefault(); RequestConfig requestConfig = RequestConfig.custom() .setConnectionRequestTimeout(10000) .setConnectTimeout(5000) .build(); HttpPost httpPost = new HttpPost(url); MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create(); // 解决中文文件名乱码问题 entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); entityBuilder.setCharset(Consts.UTF_8); ContentType contentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), Consts.UTF_8); entityBuilder.addBinaryBody("file", file.getInputStream(), ContentType.DEFAULT_BINARY, file.getOriginalFilename()); httpPost.setEntity(entityBuilder.build()); httpPost.setConfig(requestConfig); HttpResponse execute = httpclient.execute(httpPost); String flag = EntityUtils.toString(execute.getEntity()); return flag; }
总结:远程调用使用了RestTemplate和httpclient也可以使用feign,但是RestTemplate和feign大文件会OOM(所以适用于小文件传输,约在1G以下),httpclient不会。
方案二:一句话总结,将前端传入的MultipartFile通过临时文件转为FileSystemResource,再将临时文件删除
最终解决方案:将图片放在一个temp文件夹,方便统一删除。
@RequestMapping("/upload")
public void postData(@RequestParam("file") MultipartFile file) throws IOException {
String url = "https://localhost:8080/upload";
MultiValueMap<String, Object> bodyMap = new LinkedMultiValueMap<>();
bodyMap.add("file", new FileSystemResource(convert(file)));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(bodyMap, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(url,
HttpMethod.POST, requestEntity, String.class);
}
public static File convert(MultipartFile file)
{
File convFile = new File("temp_image", file.getOriginalFilename());
if (!convFile.getParentFile().exists()) {
System.out.println("mkdir:" + convFile.getParentFile().mkdirs());
}
try {
convFile.createNewFile();
FileOutputStream fos = new FileOutputStream(convFile);
fos.write(file.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
return convFile;
}
转自:关于springboot 中使用httpclient或RestTemplate做MultipartFile文件跨服务传输的问题-云海天教程
Springboot 中使用 RestTemplate 向另一个 RESTful api 请求 multipart file 报错_thothsun 的博客-CSDN博客