[英]Required request part 'file' is not present - Angular2 Post request
I am trying to get my file upload functionality done using Angular2 and SpringBoot.我正在尝试使用 Angular2 和 SpringBoot 完成我的文件上传功能。 I can certify that my java code for the file uploading working fine since I have tested it successfully using Postman.我可以证明我的用于文件上传的 java 代码工作正常,因为我已经使用 Postman 成功测试了它。
However, when it comes to sending the file from Angular2 front end, I am getting the HTTP 400 response saying Required request part 'file' is not present
.但是,当涉及到从 Angular2 前端发送文件时,我收到 HTTP 400 响应说Required request part 'file' is not present
。
This is how I send the POST request from Angular2.这就是我从 Angular2 发送 POST 请求的方式。
savePhoto(photoToSave: File) {
let formData: FormData = new FormData();
formData.append('file', photoToSave);
// this will be used to add headers to the requests conditionally later using Custom Request Options
this._globals.setRequestFrom("save-photo");
let savedPath = this._http
.post(this._endpointUrl + "save-photo", formData)
.map(
res => {
return res.json();
}
)
.catch(handleError);
return savedPath;
}
Note that I have written a CustomRequestOptions
class which extends BaseRequestOptions
in order to append Authorization header and Content Type header.请注意,我编写了一个CustomRequestOptions
类,它扩展了BaseRequestOptions
以附加 Authorization 标头和 Content Type 标头。 Content Type header will be added conditionally.内容类型标题将有条件地添加。
Following is the code for that.以下是代码。
@Injectable()
export class CustomRequestOptions extends BaseRequestOptions {
constructor(private _globals: Globals) {
super();
this.headers.set('X-Requested-By', 'Angular 2');
this.headers.append('virglk', "vigamage");
}
merge(options?: RequestOptionsArgs): RequestOptions {
var newOptions = super.merge(options);
let hdr = this._globals.getAuthorization();
newOptions.headers.set("Authorization", hdr);
if(this._globals.getRequestFrom() != "save-photo"){
newOptions.headers.set('Content-Type', 'application/json');
}else{
//request coming from save photo
console.log("request coming from save photo");
}
return newOptions;
}
}
This conditional header appending is working fine.此条件标头附加工作正常。 The purpose of doing that is if I add 'Content-Type', 'application/json'
header to every request, file upload method in Spring controller will not accept it.这样做的目的是,如果我向每个请求添加'Content-Type', 'application/json'
标头,Spring 控制器中的文件上传方法将不会接受它。 (Returns http 415) (返回 http 415)
Everything seems to be fine.一切似乎都很好。 But I get Required request part 'file' is not present
error response.但我得到Required request part 'file' is not present
错误响应。 Why is that?这是为什么? I am adding that param to the form Data.我将该参数添加到表单数据中。
let formData: FormData = new FormData();
formData.append('file', photoToSave);
This is the Spring Controller method for your reference.这是 Spring Controller 方法供您参考。
@RequestMapping(method = RequestMethod.POST, value = "/tender/save-new/save-photo", consumes = {"multipart/form-data"})
public ResponseEntity<?> uploadPhoto(@RequestParam("file") MultipartFile file){
if (file.isEmpty()) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setMessage("DEBUG: Attached file is empty");
return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.NOT_FOUND);
}
String returnPath = null;
try {
// upload stuff
} catch (IOException e) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setMessage(e.getMessage());
return new ResponseEntity<ErrorResponse> (errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity<String>(returnPath, HttpStatus.OK);
}
EDIT - Adding the payload of the request captured by the browser编辑- 添加浏览器捕获的请求的负载
As you can see, the param "file" is available there.如您所见,参数“文件”在那里可用。
Try to add 尝试添加
headers: {
'Content-Type': 'multipart/form-data'
},
to your 到你的
.post(this._endpointUrl + "save-photo", formData)
Change formData.append('file', photoToSave);
更改formData.append('file', photoToSave);
to到formData.append('file', this.photoToSave, this.photoToSave.name);
and also add headers specifying the type of data you are passing to API, in your case it will be并添加标头,指定您传递给 API 的数据类型,在您的情况下,它将是'Content-Type': 'multipart/form-data'
. 'Content-Type': 'multipart/form-data'
。 Post the output here if it fails even after changing this.如果更改后仍然失败,请在此处发布输出。
Is there a chance that you're using zuul in a secondary app that is forwarding the request?您是否有可能在转发请求的辅助应用程序中使用 zuul? I saw this with an update where the headers were stripped while forwarding a multi-part upload.我在一个更新中看到了这一点,其中在转发多部分上传时去除了标题。 I have a gatekeeper app which forwards requests using zuul to the actual service via a looking from eureka.我有一个看门人应用程序,它通过从尤里卡的观察使用 zuul 将请求转发到实际服务。 I fixed it by modifying the url like this:我通过像这样修改 url 来修复它:
http://myserver.com/service/upload http://myserver.com/service/upload
to到
http://myserver.com/zuul/service/upload http://myserver.com/zuul/service/upload
Suddenly the 'file' part of the upload header was no longer stripped away and discarded.突然,上传标题的“文件”部分不再被剥离和丢弃。
The cause, I suspect was a re-try mechanism which cached requests.我怀疑原因是缓存请求的重试机制。 On failure, it would re-submit the requests, but somehow for file uploads, it wasn't working properly.失败时,它会重新提交请求,但不知何故对于文件上传,它无法正常工作。
FormData
and set content type as multipart/form-data
.要将文件上传到服务器,请将文件发送到FormData
并将内容类型设置为multipart/form-data
。
export const uploadFile = (url, file, onUploadProgress) => {
let formData = new FormData();
formData.append("file", file);
return axios.post(url, formData, {
headers: {
'Content-Type': 'multipart/form-data;charset=UTF-8',
// other headers
},
onUploadProgress,
})
};
consumes
attribute and @RequestPart
annotation here.要处理文件对象,请注意这里的consumes
属性和@RequestPart
注释。@PostMapping(value = "/your-upload-path", consumes = "multipart/form-data")
public ResponseEntity<Object> uploadFile(@RequestPart("file") @Valid @NotNull @NotBlank MultipartFile file) {
// .. your service call or logic here
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.