getOriginalFilename方法与“文件名、目录名或卷标语法不正确”

之前写了一篇博文关于multiple标签简单使用的文章,在回复网友问题关于IE11浏览器支持时,发现程序在IE11和Edge浏览器下报错

java.io.IOException: java.io.FileNotFoundException: D:\DEV_ENV\upload\C:\Users\PC\Downloads\团险业务概念与特点.ppt (文件名、目录名或卷标语法不正确。)

错误信息很明显,程序找不到D:\DEV_ENV\upload\C:\Users\PC\Downloads\团险业务概念与特点.ppt这个文件

细看一眼,好像有问题,这个文件的路径有错,前面是带有盘符的路径信息,后面又有盘符的路径信息

查看代码后,发现问题的症结

	/**
	 * 文件保存方法
	 * @param file
	 * @param destination
	 * @throws IOException 
	 * @throws IllegalStateException 
	 */
	private void saveFile(MultipartFile file, String destination) throws IllegalStateException, IOException {
		// 获取上传的文件名称,并结合存放路径,构建新的文件名称
		String filename = file.getOriginalFilename();
		
		File filepath = new File(destination, filename);
		
		// 判断路径是否存在,不存在则新创建一个
		if (!filepath.getParentFile().exists()) {
			filepath.getParentFile().mkdirs();
		}
		
		// 将上传文件保存到目标文件目录
		file.transferTo(new File(destination + File.separator + filename));
	}

代码中file.getOriginalFilename() 获取上传的文件名称,但是在IE11/Edge浏览器下面,获取到的路径信息带有盘符

查看该方法定义

	/**
	 * Return the original filename in the client's filesystem.
	 * <p>This may contain path information depending on the browser used,
	 * but it typically will not with any other than Opera.
	 * @return the original filename, or the empty String if no file has been chosen
	 * in the multipart form, or {@code null} if not defined or not available
	 * @see org.apache.commons.fileupload.FileItem#getName()
	 * @see org.springframework.web.multipart.commons.CommonsMultipartFile#setPreserveFilename
	 */
	@Nullable
	String getOriginalFilename();

最上面两句含义便是,该方法返回文件在客户端文件系统中的原始文件名称,该名称或许会包含路径信息,这点依赖于浏览器。

由于之前的测试都是在Chrome浏览器,未测试IE11浏览器,故未发现该问题。

修复该问题,在代码中增加浏览器的判断

扫描二维码关注公众号,回复: 12685263 查看本文章
		// 获取上传的文件名称,并结合存放路径,构建新的文件名称
		String filename = file.getOriginalFilename();
		
		// 文件上传时,Chrome和IE/Edge对于originalFilename处理不同
		// Chrome 会获取到该文件的直接文件名称,IE/Edge会获取到文件上传时完整路径/文件名
		
		// Check for Unix-style path
		int unixSep = filename.lastIndexOf('/');
		// Check for Windows-style path
		int winSep = filename.lastIndexOf('\\');
		// Cut off at latest possible point
		int pos = (winSep > unixSep ? winSep : unixSep);
		if (pos != -1)  {
			// Any sort of path separator found...
			filename = filename.substring(pos + 1);
		}
		
		File filepath = new File(destination, filename);

这段系统路径分隔符的判断,来自于org.springframework.web.multipart.commons.CommonsMultipartFile类的getOriginalFilename() 方法内。增加后,若为带有路径的文件名信息,则截取我们实际需要的文件名信息。

修改后,测试上传无误,这里就不贴测试信息了。

猜你喜欢

转载自blog.csdn.net/magi1201/article/details/86736648