项目场景:
在后端使用MultipartFile处理上传附件,项目部署到weblogicServer后报错
问题描述:
报错信息为:
java.io.FileNotFoundException: D:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\servers\AdminServer\tmp_WL_user\weixin2021\3e1l3m\public</font>D:\fileSave\attachment2021\11\24\test.jpg (文件名、目录名或卷标语法不正确。)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.(FileOutputStream.java:213)
at java.io.FileOutputStream.(FileOutputStream.java:162)
at weblogic.servlet.utils.fileupload.PartItem.write(PartItem.java:455)
at weblogic.servlet.utils.fileupload.PartItem.write(PartItem.java:487)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.transferTo(StandardMultipartHttpServletRequest.java:256)
at com.picc.weixin2021.controller.FileAction.fileUpload(FileAction.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
原因分析:
我拼接后的绝对路径为: “D:\fileSave\attachment2021\11\24\test.jpg”,而它自动拼接到了weblogic临时文件目录
(D:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\servers\AdminServer\tmp_WL_user\weixin2021\3e1l3m\public),
在tomcat中运行正常,那么就是weblogic的问题,看报错信息中找到
weblogic.servlet.utils.fileupload.PartItem.write(PartItem.java:487),
看路径像是weblogic的jar包,找到这一句
public void write(String file) throws IOException {
write(new File(this.repository, file));
}
跳转至:
public PartItem(Multipart multipart, PartHeaders headers, String fieldName, String contentType, boolean isFormField, String fileName) {
this.multipart = multipart;
this.headers = headers;
this.fieldName = fieldName;
this.contentType = contentType;
this.isFormField = isFormField;
this.fileName = fileName;
this.sizeThreshold = multipart.getFileSizeThreshold();
this.repository = multipart.getRepository();
}
再跟到:
public Multipart(HttpServletRequest request, String location, long maxFileSize, long maxRequestSize, int fileSizeThreshold) {
this.request = request;
this.location = location;
this.maxFileSize = maxFileSize;
this.maxRequestSize = maxRequestSize;
this.fileSizeThreshold = fileSizeThreshold;
this.repository = (File)request.getServletContext().getAttribute("javax.servlet.context.tempdir");
if (location != null && location.length() != 0) {
File tempFile = new File(location);
if (tempFile.isAbsolute()) {
this.repository = tempFile;
} else {
this.repository = new File(this.repository, location);
}
}
}
这两句加起来等于是给我强行拼接到了临文路径.
write(new File(this.repository, file));
this.repository = (File)request.getServletContext().getAttribute(“javax.servlet.context.tempdir”);
恕我愚钝,不能理解;
看下在tomcat中的逻辑
@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);
}
}
解决方案:
1.修改weblogic的jar包中class文件,方法太妖,就不说了.
2.把MultipartFile中的流读出来,写入文件了.
//1.获取path,使用transferTo,本质是在复制流
Path path2 = file.toPath();
uploadFile.transferTo(path2);//FileUtils.copyInputStreamToFile
//interface MultipartFile的方法
default void transferTo(Path dest) throws IOException, IllegalStateException {
FileCopyUtils.copy(getInputStream(), Files.newOutputStream(dest));
}
//interface MultipartFile的方法
//2.使用org.apache.commonsorg.apache.commons的copyInputStreamToFile,本质是在复制流
InputStream inputStream = uploadFile.getInputStream();
FileUtils.copyInputStreamToFile(inputStream, file);
至此,问题解决