가짜 업로드 및 다운로드 파일 기능

함께 쓰는 습관을 들이세요! "너겟 데일리 뉴플랜·4월 업데이트 챌린지" 참여 15일차입니다. 클릭하시면 이벤트 내용을 보실 수 있습니다 .

FeignUpload다운로드

문제 배경

기본적으로 사용되는 아키텍처인 현재 주류 프레임워크 중 일부를 기반으로 파일 관리 기능 을 독립적인 예로 추출하는 微服务경우가 많습니다 .file微服务file微服务

프런트 엔드 요청, 모두 통합된 방식으로 file微服务파일 요약 기능을 호출 上传합니다 下载! ! !

이런 디자인, 통일된 관리는 문제 없을 것 같습니다! ! !

이미지.png

业务数据파일이 업로드되기 때문에 예를 들어 등을 작성해야 할 수도 있습니다. 이러한 파일은 사용 附件的信息을 위해 독립 마이크로서비스로 추출되어야 前端합니다.

그러면 문제가 발생합니다. ! ! ! T_T

1. 내 첨부 파일이 프런트엔드를 통해 업로드되지 않으면 어떻게 됩니까? 나는 백엔드 서비스이고 첨부 파일을 저장해야 합니다. 그래서 무엇을 하고 있습니까?

2. 내 백엔드의 서비스는 파일을 읽고 구문 분석해야 합니다. 분산 아키텍처이기 때문에 거기 에 file微服务배포 될 수 있습니다. 배포하려면 어떻게 해야 합니까? 이런 식으로 파일을 전혀 읽을 수 없으므로 어떻게 해야 합니까 ? 당신은 그것으로합니까? 모직 천?服务器A后端服务服务B磁盘路径

흠, 당신이 말한 것은 의미가 있습니다. 이것은 실제로 큰 문제입니다! ! !

이미지.png

당황하지 마세요. 오늘 이 문제를 해결해 드리겠습니다! ! !

시스템 에서 서비스 간의 인터페이스 호출 微服务은 일반적으로 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(),否则就算获取到该流,也无法处理业务逻辑。

이미지.png

好了,上面就是咋们定义好的feign接口,和提供服务的file微服务上传下载接口!!!

上传下载接口,只是给出一个demo,大家伙,可自行修改,相应的业务逻辑!!!^_^

Feign上传下载

接下来,咋们就开始使用到这个feign上传下载功能!!!

이미지.png

  • 上传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流被关闭了,无法再使用,即不能处理业务逻辑代码了!!!

이미지.png

好了,这个就是上传文件的示例,也是比较简单啦!!!

好了,Feign上传和下载,大概的实现,就是这样了!!!^_^

그러면 우리는 행복하게 코드를 작성할 수 있습니다! ! ! ^_^

이미지.png

추천

출처juejin.im/post/7086827087260024845