文件上傳配置:
<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