함께 쓰는 습관을 들이세요! "너겟 데일리 뉴플랜·4월 업데이트 챌린지" 참여 15일차입니다. 클릭하시면 이벤트 내용을 보실 수 있습니다 .
FeignUpload다운로드
문제 배경
기본적으로 사용되는 아키텍처인 현재 주류 프레임워크 중 일부를 기반으로 파일 관리 기능 을 독립적인 예로 추출하는 微服务
경우가 많습니다 .file
微服务
file微服务
프런트 엔드 요청, 모두 통합된 방식으로 file微服务
파일 요약 기능을 호출 上传
합니다 下载
! ! !
이런 디자인, 통일된 관리는 문제 없을 것 같습니다! ! !
业务数据
파일이 업로드되기 때문에 예를 들어 등을 작성해야 할 수도 있습니다. 이러한 파일은 사용 附件的信息
을 위해 독립 마이크로서비스로 추출되어야 前端
합니다.
그러면 문제가 발생합니다. ! ! ! T_T
1. 내 첨부 파일이 프런트엔드를 통해 업로드되지 않으면 어떻게 됩니까? 나는 백엔드 서비스이고 첨부 파일을 저장해야 합니다. 그래서 무엇을 하고 있습니까?
2. 내 백엔드의 서비스는 파일을 읽고 구문 분석해야 합니다. 분산 아키텍처이기 때문에 거기 에
file微服务
배포 될 수 있습니다. 배포하려면 어떻게 해야 합니까? 이런 식으로 파일을 전혀 읽을 수 없으므로 어떻게 해야 합니까 ? 당신은 그것으로합니까? 모직 천?服务器A
后端服务
服务B
磁盘路径
흠, 당신이 말한 것은 의미가 있습니다. 이것은 실제로 큰 문제입니다! ! !
당황하지 마세요. 오늘 이 문제를 해결해 드리겠습니다! ! !
시스템 에서 서비스 간의 인터페이스 호출 微服务
은 일반적으로 feign
디튜닝을 통해 수행되기 때문입니다. 그래서, 파일을 통해서도 feign
호출할 수 있습니까?
대답은 확실히 예입니다, 하하! ! ! ^_^
넌센스가 아니라 코드로 가자! ! !
가상 인터페이스 준비
Feign
업로드 및 다운로드 인터페이스 정의
@FeignClient(name = "file", configuration = {FileClient.MultipartSupportConfig.class})
public interface FileClient {
/**
* 上传文件
* @param file
* @return
*/
@RequestMapping(path = "/file/upload", consumes = {"multipart/form-data"})
JsonResult upload(@RequestPart(name="file") MultipartFile file);
/**
* 下载文件
*/
@GetMapping(path = "/file/download/{fileId}")
Response download(@PathVariable(name = "fileId") String fileId);
public class MultipartSupportConfig {
@Bean
@Primary
@Scope("prototype")
public Encoder feignFormEncoder() {
return new SpringFormEncoder();
}
}
}
复制代码
file微服务
파일上传
인터페이스 제공
@RequestMapping("/file/upload")
public JsonResult upload(MultipartHttpServletRequest request) throws Exception {
JsonResult jsonResult = new JsonResult();
String timestamp = request.getParameter("time");
MultiValueMap<String, MultipartFile> multiFileMap = request.getMultiFileMap();
List<MultipartFile> files = multiFileMap.get("files");
if (BeanUtil.isEmpty(files)) {
files = multiFileMap.get("file");
}
Iterator<MultipartFile> it = files.iterator();
while (it.hasNext()) {
MultipartFile multipartFile = it.next();
//保存到磁盘
multipartFile.transferTo(new File("文件路径"));
//记录文件上传业务数据
...
xxxxFileDao.saveFile(xxxFile);
}
jsonResult.setSuccess(true);
jsonResult.setData(fileList);
jsonResult.setMessage("成功上传!");
return jsonResult;
}
复制代码
file微服务
파일下载
인터페이스 제공
@GetMapping("/download/{fileId}")
public void feigndownloadOne(@PathVariable("fileId") String fileId, HttpServletResponse response) throws Exception {
//通过fileId查找文件
...
xxxFile = xxxxFileDao.getFile(fileId);
File file = new File("文件路径");
String filename = xxxFile.getName();
String type ="attachment";
response.setHeader("Content-Disposition", type + ";filename=" + filename);
FileInputStream fis = new FileInputStream(file);
BufferedInputStream buff = null;
OutputStream out = null;
try {
buff = new BufferedInputStream(fis);
out = response.getOutputStream();
IOUtils.copy(buff, out);
} finally {
out.flush();//注意out流,对象不能close
fis.close();
buff.close();
}
}
复制代码
下载
这个接口,有个比较重要的地方就是,out
流,不能close()
,否则就算获取到该流,也无法处理业务逻辑。
好了
,上面就是咋们定义好的feign接口,和提供服务的file微服务
上传下载接口!!!
上传下载接口,只是给出一个demo,大家伙,可自行修改,相应的业务逻辑!!!^_^
Feign上传下载
接下来,咋们就开始使用到这个feign
的上传下载
功能!!!
- 上传
feign接口
,使用
import java.io.File;
import java.io.FileInputStream;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.mock.web.MockMultipartFile;
import org.apache.http.entity.ContentType;
File pdfFile = new File("D://test.pdf");
FileInputStream fileInputStream = new FileInputStream(pdfFile);
MultipartFile multipartFile = new MockMultipartFile(pdfFile.getName(), pdfFile.getName(),
ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
//上传
JsonResult jsonResult = fileClient.upload(multipartFile);
if (jsonResult.isSuccess() && jsonResult.getCode() == 200) {
}
复制代码
注意了
注意了
注意了
!!!
这里,有个要注意的地方,因为我们的
upload
接口,即controller
接口一般使用MultipartFile
对象接收文件,那么我们就得把File
,对象先转成MultipartFile
对象,才可以调通这个接口!!!转换方式,看上面代码即可!!!
好了,这个就是上传文件的示例
,也是比较简单
啦!!!
- 下载
feign接口
,使用
import feign.Response;
//文件流
Response response = fileClient.download(fileId);
InputStream in = null;
if(response.status() == 200){
Response.Body body = response.body();
in = body.asInputStream();
//拿到这个in流,处理相应的业务逻辑
...
//处理完成后,记得关闭一下inputStream流
if(in != null){
in.close();
}
}
复制代码
注意了
注意了
注意了
!!!
这里有两个地方需要注意:
1.因为我们的download接口,
out
流是还没有close()
,所以这里的in
流,用完得close()
一下。2.这里的代码,在开发过程中,不能
打断点调试
,不能打断点调试
,不能打断点调试
!!!重要的事情得说三遍,不能
打断点调试
,因为你断点调试后
,这里的in
流,会因为执行了toString()
方法,导致in
流被关闭
了,无法再使用,即不能处理业务逻辑代码了!!!
好了,这个就是上传文件的示例
,也是比较简单
啦!!!
好了,Feign
上传和下载,大概的实现,就是这样了!!!^_^
그러면 우리는 행복하게 코드를 작성할 수 있습니다! ! ! ^_^