zoukankan      html  css  js  c++  java
  • SpringMvc上传文件遇到重复读取InputStream的问题


    文件上传配置:

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
      <property name="defaultEncoding" value="utf-8"></property>
      <property name="maxUploadSize" value="10485760000"></property>
      <property name="maxInMemorySize" value="40960"></property>
    </bean>
    

    Controller代码

    @RequestMapping("/file")
    @RestController
    public class HelloController {
      @Autowired
      private UploadService uploadService;
    
      @RequestMapping(value="/upload", method= RequestMethod.POST)
      public void upload(@RequestParam(value = "file", required = true) MultipartFile file) {
        String md5 = DigestUtils.md5Hex(file.getInputStream()); //使用commons-codec计算md5
        uploadService.upload(file.getInputStream());
      }
    }
    

    单元测试代码

    @ContextConfiguration(locations = "classpath*:META-INF/spring/spring-*.xml")
    @RunWith(SpringJUnit4ClassRunner.class)
    public class UploadServiceTests extends BaseTests {
        private static final Logger logger = LoggerFactory.getLogger(UploadServiceTests.class);
    
        @Autowired
        private UploadService uploadService;
    
        @Test
        public void upload() throws Exception {
          Integer num = new Random().nextInt(9999999);
          byte[] bytes = ("HelloWorld-" + num).getBytes();
          InputStream inputStream = new ByteArrayInputStream(bytes);
          String md5 = MD5Utils.getMD5(inputStream);
          uploadService.upload(inputStream);
        }
    }
    

    遇到问题:
    Controller代码可以正常上传,而单元测试代码上传只有0字节

    原因:
    在计算stream的md5时,已经将流的游标移动到了最后,如果不做任何处理直接使用,则无法再从流里读到字节。而Controller里的file.getInputStream()实际每次返回的并不是同一个流,也就是计算md5和传给upload方法的并不是同一个stream,所以Controller里的upload成功的取到了数据。单元测试的stream时手动创建的,计算md5和upload的都是同一个流,所以upload时流的游标已经在尾部了。

    修改单元测试代码为:

    InputStream inputStream = new ByteArrayInputStream(bytes);
    inputStream.mark(0);
    String md5 = MD5Utils.getMD5(inputStream);
    inputStream.reset();
    

    关于mark和reset的理解,可以参考通过mark和reset方法重复利用InputStream

  • 相关阅读:
    LeetCode 230. Kth Smallest Element in a BST
    LeetCode 114. Flatten Binary Tree to Linked List
    LeetCode 222. Count Complete Tree Nodes
    LeetCode 129. Sum Root to Leaf Numbers
    LeetCode 113. Path Sum II
    LeetCode 257. Binary Tree Paths
    Java Convert String & Int
    Java Annotations
    LeetCode 236. Lowest Common Ancestor of a Binary Tree
    LeetCode 235. Lowest Common Ancestor of a Binary Search Tree
  • 原文地址:https://www.cnblogs.com/liqipeng/p/7452685.html
Copyright © 2011-2022 走看看