当前位置:   article > 正文

接收第三方系统的附件文件转为MultipartFile对象进行存储_接收第三方文件信息和附件

接收第三方文件信息和附件

最近遇到一个和第三方系统系统对接,碰到的一个附件问题,由于没有指定标准,导致被牵着鼻子走,浪费了大量的时间,话不多说,上问题,及解决方法

遇到的问题:第三方系统推送附件,我这边使用MultipartFile 进行接收,是没问题的,但是一直出现附件上传服务器上下载下来打不开损坏了。后来想了一个办法之间传过来一个压缩包我接收保存,压缩包可以正常上传,下载,文件也没有问题,但是由于不能直接上传压缩包,只能是在代码里面解压压缩包,然后上传附件。

此时在解压的过程中也没有报错,但是又出现了老问题就是上传的附件下载下来损坏了,此时我就觉得可能是在读取文件的时候,转为MultipartFile对象的时候出问题(因为已经有写好的方法,直直接传参数就行),但是我通过接口测试工具测试还是可以上传压缩包,不能解压。

那会不会是文件读取的问题呢?

此时,我就将读取的文件输出到本地,果然,读取文件出现问题,那么问题已经定位到,哈哈哈

1.controller

  1. @PostMapping("/createInstructions")
  2. public AjaxResult createInstructions(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "file") MultipartFile file) {
  3. if (oaService.mapping(request, response, file)) {
  4. return AjaxResult.success();
  5. }
  6. return AjaxResult.error();
  7. }

2.service

boolean mapping(HttpServletRequest request, HttpServletResponse response,  MultipartFile file);
  1. @Transactional
  2. @Override
  3. public boolean mapping(HttpServletRequest request, HttpServletResponse response, MultipartFile file) {
  4. MultipartFile multipartFile = null;
  5. String originalFilename = file.getOriginalFilename() ;
  6. if (!originalFilename.endsWith(".zip")){
  7. throw new RuntimeException( originalFilename+"文件格式错误请上传.zip");
  8. }
  9. List<MultipartFile> multipartFileList = new ArrayList<>();
  10. ZipArchiveInputStream zipInputStream = null;
  11. BufferedInputStream bufferedInputStream = null;
  12. String zipEntryFile;
  13. try {
  14. zipInputStream = new ZipArchiveInputStream(file.getInputStream(), Charset.forName("UTF-8").toString());
  15. bufferedInputStream = new BufferedInputStream(zipInputStream) ;
  16. ZipEntry zipEntry;
  17. while ((zipEntry = zipInputStream.getNextZipEntry()) != null){
  18. if (zipEntry.isDirectory()) {
  19. continue;
  20. }else{
  21. zipEntryFile = zipEntry.getName();
  22. Assert.notNull(zipEntryFile,"压缩文件中子文件的名字格式不正确");
  23. byte[] bytes = new byte[(int)zipEntry.getSize()];
  24. bufferedInputStream.read(bytes,0,(int)zipEntry.getSize());
  25. InputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
  26. String contentType = MediaTypeFactory.getMediaType(zipEntryFile).orElse(MediaType.APPLICATION_OCTET_STREAM).toString();
  27. MultipartFile mockMultipartFile = new MockMultipartFile(zipEntryFile, zipEntryFile, contentType, byteArrayInputStream);
  28. multipartFileList.add(multipartFile);
  29. SysAttachment attachment = new SysAttachment();
  30. Long fileId = SnowFlake.getId();
  31. attachment.setFileid(fileId);
  32. String tempFilePath = tempPath + SnowFlake.getId() + File.separator;
  33. AjaxFileResult ajaxFileResult = sysAttachmentService.uploadServerFile(attachment, mockMultipartFile, tempFilePath);
  34. Integer state = ajaxFileResult.getState();
  35. if(state == 200){
  36. SysAttachment sysAttachment = sysAttachmentService.selectSysAttachmentById(fileId);
  37. OafileDetail detail = getOaDetail(sysAttachment,master.getId());
  38. logger.info("OA文件细明对象--------detail:{}", detail);
  39. oafileDetailMapper.insertSelective(detail); // oa文件细明对象
  40. logger.info("OA______________detail表插入成功-------string");
  41. }
  42. FileOutputStream fileOutputStream = null;
  43. try {
  44. fileOutputStream = new FileOutputStream(tempPath + zipEntryFile);
  45. byte[] buffer = new byte[1024];
  46. int length;
  47. while ((length = byteArrayInputStream.read(buffer)) > 0) {
  48. fileOutputStream.write(buffer, 0, length);
  49. }
  50. } catch (Exception e) {
  51. e.printStackTrace();
  52. }
  53. multipartFileList.add(multipartFile);
  54. byteArrayInputStream.close();
  55. }
  56. }
  57. } catch ( IOException e){
  58. e.printStackTrace();
  59. }finally {
  60. if (bufferedInputStream!=null) {
  61. try {
  62. bufferedInputStream.close();
  63. } catch (IOException e) {
  64. e.printStackTrace();
  65. }
  66. }
  67. if (zipInputStream != null) {
  68. try {
  69. zipInputStream.close();
  70. } catch (IOException e) {
  71. e.printStackTrace();
  72. }
  73. }
  74. }
  75. }

上述代码的问题:就是上传到服务器上下载下来损坏了,其实就是读取的时候出问题,优化后的代码如下:

  1. @Transactional
  2. @Override
  3. public boolean mapping(HttpServletRequest request, HttpServletResponse response, MultipartFile file) {
  4. try (ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(file.getInputStream(), Charset.forName("UTF-8").toString())) {
  5. ZipEntry zipEntry;
  6. while ((zipEntry = zipInputStream.getNextZipEntry()) != null) {
  7. if (zipEntry.isDirectory()) {
  8. continue;
  9. } else {
  10. String zipEntryFile = zipEntry.getName();
  11. Assert.notNull(zipEntryFile, "压缩文件中子文件的名字格式不正确");
  12. // 创建缓冲区
  13. byte[] buffer = new byte[4096];
  14. int bytesRead;
  15. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  16. // 逐个读取文件内容
  17. while ((bytesRead = zipInputStream.read(buffer, 0, buffer.length)) != -1) {
  18. outputStream.write(buffer, 0, bytesRead);
  19. }
  20. // 创建MultipartFile对象
  21. byte[] fileBytes = outputStream.toByteArray();
  22. InputStream byteArrayInputStream = new ByteArrayInputStream(fileBytes);
  23. String contentType = MediaTypeFactory.getMediaType(zipEntryFile).orElse(MediaType.APPLICATION_OCTET_STREAM).toString();
  24. MultipartFile mockMultipartFile = new MockMultipartFile(zipEntryFile, zipEntryFile, contentType, byteArrayInputStream);
  25. byteArrayInputStream.close();
  26. outputStream.close();
  27. // 上传文件并处理结果
  28. SysAttachment attachment = new SysAttachment();
  29. Long fileId = SnowFlake.getId();
  30. attachment.setFileid(fileId);
  31. String tempFilePath = tempPath + SnowFlake.getId() + File.separator;
  32. AjaxFileResult ajaxFileResult = sysAttachmentService.uploadServerFile(attachment, mockMultipartFile, tempFilePath);
  33. Integer state = ajaxFileResult.getState();
  34. if (state == 200) {
  35. SysAttachment sysAttachment = sysAttachmentService.selectSysAttachmentById(fileId);
  36. OafileDetail detail = getOaDetail(sysAttachment, master.getId());
  37. logger.info("文件细明对象--------detail:{}", detail);
  38. oafileDetailMapper.insertSelective(detail); // oa文件细明对象
  39. logger.info("OA______________detail表插入成功-------string");
  40. }
  41. }
  42. }
  43. } catch (IOException e) {
  44. e.printStackTrace();
  45. }
  46. }

为什么这样写就好了?

字节读取问题:在读取zipEntry的内容时,创建了一个大小为(int)zipEntry.getSize()的字节数组,并使用bufferedInputStream.read方法将字节数据读取到数组中。然而,这种方式可能会导致字节数组大小不足以容纳整个文件内容,从而导致文件损坏。为了解决这个问题,建议使用较小的缓冲区,逐个读取和写入文件内容,而不是一次性读取整个文件内容。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号