SpringCloud-Alibaba微服务中关于使用OpenFeign远程调用上传下载的坑
1.上传服务
1.1上传服务提供端
服务提供者(生产者)代码示例,以常见的MultipartFile作为接收:
@PostMapping(value = "/xxxxx", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Object xxxxxxx(MultipartFile file) {
log.info(file.getOriginalFilename());
Object object = new Object();
String UPLOAD_FOLDER = System.getProperty("user.dir") + "/uploadFile/";
if (Objects.isNull(file) || file.isEmpty()) {
log.error("文件为空");
object = "文件为空,请重新上传";
}
try {
byte[] bytes = file.getBytes();
Path path = Paths.get(UPLOAD_FOLDER + file.getOriginalFilename());
//如果没有files文件夹,则创建
if (!Files.isWritable(path)) {
Files.createDirectories(Paths.get(UPLOAD_FOLDER));
}
//文件写入指定路径
Files.write(path, bytes);
log.debug("文件写入成功...");
object = "文件上传成功";
} catch (IOException e) {
e.printStackTrace();
object = "后端异常...";
}
retrun object;
}
1.2上传服务调用端
配置Encoder
@Configuration
public class MultipartSupportConfig {
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
public Encoder feignFormEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
}
服务调用注解
@FeignClient(value = "xxxx-provider",fallback = xxx.class,configuration = MultipartSupportConfig.class)
@RequestMapping("/xxx")
@Service("waterRegimeService")
public interface xxxxxService {
@PostMapping(value = "/upload",
produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
Object xxxxxxxx(@RequestPart(value = "file") MultipartFile file);
}
注意用@RequestPart接收 ,括号内用value
2.下载服务
2.1下载服务提供端
下载代码示例:
@RequestMapping(value = "/xxxxx")
public static Object xxxxxx(HttpServletResponse response) throws Exception {
String resPath = "xxx";
String resName = "xxx";
//设置文件路径
File file = new File(resPath, resName);
// 如果文件名存在,则进行下载
if (file.exists()) {
// 配置文件下载
response.setHeader("content-type", "application/octet-stream");
response.setContentType("application/octet-stream");
// 下载文件能正常显示中文
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(resName, "UTF-8"));
// 实现文件下载
byte[] buffer = new byte[1024];
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
System.out.println("Download the song successfully!");
} catch (Exception e) {
System.out.println("Download the song failed!");
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return null;
}
2.2下载服务调用端
@RequestMapping("/xxxxx")
Response xxxx() throws Exception;
注意:此处使用OpenFeign的Response接收
controller处:
@RequestMapping("/xxxxxx")
public String download(HttpServletResponse response) throws Exception {
response.setHeader("content-type", "application/octet-stream");
response.setContentType("application/octet-stream");
// 下载文件能正常显示中文
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("xxxxx.xxx", "UTF-8"));
OutputStream outputStream = response.getOutputStream();//因为服务B中没有返回值的,但是这里它需要把文件给保留下来,所以使用Response接收参数
Response r = xxxRegimeService.downLoadExcel();
InputStream stream = r.body().asInputStream();
IOUtils.copy(stream, outputStream);
return null;
}