最近项目上碰到一个问题,需要将一个大字符串转成文件使用的feign的方式调用另一个同一个注册中心的文件处理系统,最重要的是不想在服务器上临时创建文件,如果不能及时删除会占用服务器的存储空间,如果是一个成熟的系统需要监控保存问价的这个地址来保证稳定性。所以想着使用什么方式解决这个问题。
第一步,我们上传文件的接收对象都是MultipartFile,就从这个文件开始研究;文件上传的时候需要分清楚两个名称,一个是字段名,一个是文件名。
MultipartFile是一个接口,里面有getName()方法用来获取MultipartFile的字段名,getOriginalFilename()用来获取文件名,getInputStream()用来获取文件的流信息,可以通过transferTo()将文件保存到某一个文件中。
第二步,我想了解下我们的系统在接收到MultipartFile的时候整个处理流程。
首先:DispatcherServlet在刷新的时候会调用initStrategies()调用初始化initMultipartResolver(context);在真正的doDispatch()的时候调用checkMultipart(HttpServletRequest request);检查MultipartFile格式,这个方法中会调用MultipartResolver接口的实现方法中的resolveMultipart(HttpServletRequest request),一般情况有两种实现,一种是CommonsMultipartResolver,一种是StandardServletMultipartResolver。CommonsMultipartResolver需要使用 Apache 的 commons-fileupload 等 jar 包支持,但它能在比较旧的 servlet 版本中使用;StandardServletMultipartResolver不需要第三方 jar 包支持,它使用 servlet 内置的上传功能,但是只能在 Servlet 3 以上的版本使用。
第三步,因为MultipartFile是接口,上传中需要将string类型转成MultipartFile的两种实现,一种是StandardServletMultipartResolver对应的StandardMultipartFile,一种是CommonsMultipartResolver对应的CommonMultipartFile,在这里我借助的是CommonMultipartFile。贴下代码
public String uploadStringData(String filePath, String fileName, String uploadContent) { String fileUrl = null; HttpHeaders headers = new HttpHeaders(); byte[] fileContent = uploadContent.getBytes(); headers.setContentType(MediaType.MULTIPART_FORM_DATA);
FileItemFactory factory = new DiskFileItemFactory(); String textFieldName = "file"; FileItem item = factory.createItem(textFieldName, "multipart/form-data", true, fileName + ".txt");
MultipartFile file = new CommonsMultipartFile(item); log.info("uploadStringData: item origin file name = {}, field name = {}", item.getName(), item.getFieldName()); UploadFileResponse response = fileCenterFeign.uploadFile(FILE_SOURCE, filePath, file); log.info("uploadStringData: response = {}", response.toString()); return response.getFileUrl(); } |
第四步,提醒下,如果我们传输的时候一定要注意MultipartFile 的字段名,不能和接收的有区别,不然无法正常接收。使用postman的时候不需要在添加头信息,postman会自动添加,负责会报错。