控制层
@RequestMapping(value = "/onModify", method = RequestMethod.POST)
@ResponseBody
public String editMapManager(@RequestParam MultipartFile[] mapUrl, HttpServletRequest request) {
try {
if (mapUrl.length > 0) {
for (MultipartFile mf : mapUrl) {
if (mf.getSize() > 0) {
String path = getPhotoUrl();//存储路径
String fileName = mf.getOriginalFilename();//文件名
String type = fileName.substring(fileName.lastIndexOf(".") + 1);// 文件类型
fileName = UUID.randomUUID() + fileName.substring(fileName.lastIndexOf("."));//拼接文件名
File targetFile = new File(path, fileName);//
if (!targetFile.exists()) {
targetFile.mkdirs();
}
mf.transferTo(targetFile);
}
}
}
} catch (Exception e) {
e.printStackTrace();
return getReturnJSON(2, JsMessage.C0006, false);
}
return getReturnJSON(1, JsMessage.C0005, true);
}
Junit测试
@Test
public void editMapManaxger() throws Exception {
MockMultipartFile firstFile = null;
File file = new File("D:/jd1.svg");
firstFile = new MockMultipartFile("mapUrl", MAP_NAME , "multipart/form-data", new FileInputStream(file));
// File file = new File(FILE_BASE_PATH+MAP_NAME);
// firstFile = new MockMultipartFile("filePath", MAP_NAME , "multipart/form-data", new FileInputStream(file));
MockHttpServletRequestBuilder request = null;
request = MockMvcRequestBuilders.fileUpload("/mapManager/onModify").file(firstFile)
.param("mapVariety", "1").param("id", "2")
.param("name", "test").param("scale", "1000");
MvcResult result = mvc.perform(request
.session((MockHttpSession) getLoginSession()))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn();
}
问题说明
以上代码项目正常运行时没有问题 。倒是运行上面测试用例,会抛出“拒绝访问”。
原因
if (!targetFile.exists()) {
targetFile.mkdirs();//递归生成文件夹,上传的文件也会先生成个文件夹
}
项目正常运行时文件传入的对象是CommonsMultipartFile,而测试用的对象是MockMultipartFile。两者都实现MultipartFile接口,但是transferTo的方法实现不同。
CommonsMultipartFile的transferTo 实现源码
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
if (!isAvailable()) {
throw new IllegalStateException("File has already been moved - cannot be transferred again");
}
if (dest.exists() && !dest.delete()) {//这一步会将上传文件生成的文件夹删除,所以可以写入。
throw new IOException(
"Destination file [" + dest.getAbsolutePath() + "] already exists and could not be deleted");
}
try {
this.fileItem.write(dest);
if (logger.isDebugEnabled()) {
String action = "transferred";
if (!this.fileItem.isInMemory()) {
action = isAvailable() ? "copied" : "moved";
}
logger.debug("Multipart file '" + getName() + "' with original filename [" +
getOriginalFilename() + "], stored " + getStorageDescription() + ": " +
action + " to [" + dest.getAbsolutePath() + "]");
}
}
catch (FileUploadException ex) {
throw new IllegalStateException(ex.getMessage());
}
catch (IOException ex) {
throw ex;
}
catch (Exception ex) {
logger.error("Could not transfer to file", ex);
throw new IOException("Could not transfer to file: " + ex.getMessage());
}
}
MockMultipartFile 的 transferTo 实现源码
向文件夹写入,所以抛出异常

本文探讨了使用MockMultipartFile进行单元测试时遇到的文件上传问题,对比了MockMultipartFile与CommonsMultipartFile在transferTo方法上的差异,并给出了可能的解决方案。
2568

被折叠的 条评论
为什么被折叠?



