从Spring Boot 1.2.7升级到1.3.1后,我面临错误MultipartFile错误一天。
我注意到默认情况是现在是Jetty 9.2而不再是Tomcat 8.在我尝试使用MultipartFile.transferTo(File file)
方法编写上传文件之前,一切都很好。
MultipartFile.transferTo()
方法正在调用javax.servlet.http.Part
的实现,这是以tomcat 8的方式实现的
@Override
public void write(String fileName) throws IOException {
File file = new File(fileName);
if (!file.isAbsolute()) {
file = new File(location, fileName);
}
try {
fileItem.write(file);
} catch (Exception e) {
throw new IOException(e);
}
}
这种方式适用于码头9.2
public void write(String fileName) throws IOException
{
if (_file == null)
{
_temporary = false;
//part data is only in the ByteArrayOutputStream and never been written to disk
_file = new File (_tmpDir, fileName);
BufferedOutputStream bos = null;
try
{
bos = new BufferedOutputStream(new FileOutputStream(_file));
_bout.writeTo(bos);
bos.flush();
}
finally
{
if (bos != null)
bos.close();
_bout = null;
}
}
else
{
//the part data is already written to a temporary file, just rename it
_temporary = false;
File f = new File(_tmpDir, fileName);
if (_file.renameTo(f))
_file = f;
}
}
Jetty实现的错误在于等待文件名File.getName()
,而不是File.getPath()
StandardMultipartHttpServletRequest.transferTo(File file)
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
this.part.write(dest.getPath());
}
这是一个错误吗?请注意,这是因为我已从spring boot 1.2.7升级到1.3.1。默认是Tomcat,现在它是Jetty ......
答案 0 :(得分:2)
根据javax.servlet.http.Part.write(String filename)
的javadoc,filename
参数是......
相对于中指定的位置创建文件 MultipartConfig
在Jetty 9.2中引用的代码中,即这个......
jetty-9.2.14.v20151106 - MultiPartInputStreamParser.write(String fileName)
您会看到它有两个可能的代码路径,第一个是内存中的""路径,第二个是'#34;磁盘上的文件"方法
在这两种情况下,当您指定Part.write(String)
的文件名时,该名称相对于您的MultiPartConfig.location
(您的问题中未详细说明的配置)。
MultiPartInputStreamParser
的实施有一个_tmpDir
which is configured from the webapp's MultiPartConfig.location
。
如果您希望此操作正常,强烈建议您定义适合您的应用程序的MultiPartConfig.location
,而不是依靠容器来选择一个。
在Part.write(String)
中允许绝对文件名的Tomcat方法实际上不允许在servlet规范中(主要是因为它可以用来对系统造成破坏的安全问题)
答案 1 :(得分:0)
好的,目前如果你想摆脱这个错误,你可以切换回Tomcat而不是Jetty。
将tomcat放入您的依赖项中:
compile('org.springframework.boot:spring-boot-starter-tomcat')
并将tomcat声明为容器:
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory();
}