将文件发布到 spring 控制器时,当前请求不是多部分
Current request is not a multipart when posting a file to a spring controller
我正在尝试向服务器发送多部分请求,但出现以下异常
org.springframework.web.multipart.MultipartException: Current request is not a multipart request
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:188)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:104)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
根据教程和 Whosebug 问题,我开发了以下代码
控制器
@RequestMapping(value = "/upload-file", method = RequestMethod.POST)
public ResponseEntity<Void> getUploadFile(@RequestParam("file") MultipartFile file) {
LOGGER.debug(String.valueOf(file));}
多部分配置
@Configuration
@EnableWebMvc
public class MultipartConfiguration {
private static final String DEFAULT_ENCODING = "UTF-8";
private static final long MAX_UPLOAD_FILE_SIZE = 100000000;
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver=new CommonsMultipartResolver();
resolver.setDefaultEncoding("utf-8");
resolver.setMaxUploadSize(MAX_UPLOAD_FILE_SIZE);
resolver.setDefaultEncoding(DEFAULT_ENCODING);
return resolver;
}
}
html
<input type="file" style="display:none" #fileupload name="image" (change)="fileProgress($event)" />
组件
export class FileUploadComponent {
fileData: any = null;
uploadedFilePath: string = null;
formData = new FormData();
reader = new FileReader();
@Output() fiLoaded: EventEmitter<File> = new EventEmitter();
constructor(private pointeService: PointeService) { }
fileProgress(fileInput: any) {
this.fileData = fileInput.target.files[0];
this.reader.readAsDataURL(this.fileData);
this.reader.onloadend = (_event) => {
this.formData.append('file', this.fileData);
this.onFileLoaded(this.formData);
};
}
onFileLoaded(formData: any) {
this.pointeService.postModifiedFileExel(formData)
.subscribe(events => {
if (events.type === HttpEventType.UploadProgress) {
} else if (events.type === HttpEventType.Response) {
// this.fileUploadProgress = 0;
console.log(events.body);
alert('SUCCESS !!');
}
});
}
}
服务
postModifiedFileExel(formData: any) {
return this.http.post(`${AppUtils.REST_API_SERVER}/espacegroupe/upload-file`, formData , {
reportProgress: true,
observe: 'events'
});
}
我还注意到我的 post 只包含文件名,不包含字节格式的数据
有什么建议吗?
对于那些仍然卡在同一个问题上的人,我将首先解释我是如何调试以找到解决方案的,其次是我做错了什么。
调试
当我处理堆栈跟踪时,我发现了两种方法负责我收到的消息,即 Current request is not a multipart request
public class ServletFileUpload extends FileUpload {
private static final String POST_METHOD = "POST";
public static final boolean isMultipartContent(HttpServletRequest request) {
return !"POST".equalsIgnoreCase(request.getMethod()) ? false : FileUploadBase.isMultipartContent(new ServletRequestContext(request));
}
.....
}
和
public abstract class FileUploadBase {
public FileUploadBase() {
}
public static final boolean isMultipartContent(RequestContext ctx) {
String contentType = ctx.getContentType();
if (contentType == null) {
return false;
} else {
return contentType.toLowerCase(Locale.ENGLISH).startsWith("multipart/");
}
}
....
}
这意味着如果您的调用不同于 POST
或者您的内容类型不是以 "multipart/"
开头,您的播放量将被视为非 multipart
我注意到我的内容类型总是 Content-Type: application/json
但是为什么我总是 Content-Type: application/json
认为 formData 应该是 Content-Type: multipart/form-data
?
在我的例子中,这是因为在应用程序中有一个 url 拦截器,它总是在 header Content-Type: application/json
.
中设置
const authReq = req.clone({setHeaders: {'Content-Type': 'application/json'}, withCredentials: true});
为确保您发送正确的数据类型,请确保在请求 Header 中您有
Content-Type: multipart/form-data;boundary=...
并且您的 formData 是二进制的。
这里有一篇 link 的文章帮助我解决了这个问题
我正在尝试向服务器发送多部分请求,但出现以下异常
org.springframework.web.multipart.MultipartException: Current request is not a multipart request
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:188)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:104)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
根据教程和 Whosebug 问题,我开发了以下代码
控制器
@RequestMapping(value = "/upload-file", method = RequestMethod.POST)
public ResponseEntity<Void> getUploadFile(@RequestParam("file") MultipartFile file) {
LOGGER.debug(String.valueOf(file));}
多部分配置
@Configuration
@EnableWebMvc
public class MultipartConfiguration {
private static final String DEFAULT_ENCODING = "UTF-8";
private static final long MAX_UPLOAD_FILE_SIZE = 100000000;
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver=new CommonsMultipartResolver();
resolver.setDefaultEncoding("utf-8");
resolver.setMaxUploadSize(MAX_UPLOAD_FILE_SIZE);
resolver.setDefaultEncoding(DEFAULT_ENCODING);
return resolver;
}
}
html
<input type="file" style="display:none" #fileupload name="image" (change)="fileProgress($event)" />
组件
export class FileUploadComponent {
fileData: any = null;
uploadedFilePath: string = null;
formData = new FormData();
reader = new FileReader();
@Output() fiLoaded: EventEmitter<File> = new EventEmitter();
constructor(private pointeService: PointeService) { }
fileProgress(fileInput: any) {
this.fileData = fileInput.target.files[0];
this.reader.readAsDataURL(this.fileData);
this.reader.onloadend = (_event) => {
this.formData.append('file', this.fileData);
this.onFileLoaded(this.formData);
};
}
onFileLoaded(formData: any) {
this.pointeService.postModifiedFileExel(formData)
.subscribe(events => {
if (events.type === HttpEventType.UploadProgress) {
} else if (events.type === HttpEventType.Response) {
// this.fileUploadProgress = 0;
console.log(events.body);
alert('SUCCESS !!');
}
});
}
}
服务
postModifiedFileExel(formData: any) {
return this.http.post(`${AppUtils.REST_API_SERVER}/espacegroupe/upload-file`, formData , {
reportProgress: true,
observe: 'events'
});
}
我还注意到我的 post 只包含文件名,不包含字节格式的数据
有什么建议吗?
对于那些仍然卡在同一个问题上的人,我将首先解释我是如何调试以找到解决方案的,其次是我做错了什么。
调试
当我处理堆栈跟踪时,我发现了两种方法负责我收到的消息,即 Current request is not a multipart request
public class ServletFileUpload extends FileUpload {
private static final String POST_METHOD = "POST";
public static final boolean isMultipartContent(HttpServletRequest request) {
return !"POST".equalsIgnoreCase(request.getMethod()) ? false : FileUploadBase.isMultipartContent(new ServletRequestContext(request));
}
.....
}
和
public abstract class FileUploadBase {
public FileUploadBase() {
}
public static final boolean isMultipartContent(RequestContext ctx) {
String contentType = ctx.getContentType();
if (contentType == null) {
return false;
} else {
return contentType.toLowerCase(Locale.ENGLISH).startsWith("multipart/");
}
}
....
}
这意味着如果您的调用不同于 POST
或者您的内容类型不是以 "multipart/"
开头,您的播放量将被视为非 multipart
我注意到我的内容类型总是 Content-Type: application/json
但是为什么我总是 Content-Type: application/json
认为 formData 应该是 Content-Type: multipart/form-data
?
在我的例子中,这是因为在应用程序中有一个 url 拦截器,它总是在 header Content-Type: application/json
.
const authReq = req.clone({setHeaders: {'Content-Type': 'application/json'}, withCredentials: true});
为确保您发送正确的数据类型,请确保在请求 Header 中您有
Content-Type: multipart/form-data;boundary=...
并且您的 formData 是二进制的。
这里有一篇 link 的文章帮助我解决了这个问题