>我有如下控制器方法:
@RequestMapping(method = RequestMethod.POST, consumes = "multipart/form-data", produces = "application/json")
public void saveUpdate(@RequestPart("org") Organization org, @RequestPart("logo") MultipartFile file){
LOG.info("ORG :"+org != null ? org.getName()+" : " + file : null);
}
在 Angular 中,我发送的表单如下所示:
public saveUpdateOrganization(organization: Organization, file: File): Observable<void> {
let headers = new Headers({ 'Content-Type': 'multipart/form-data', 'Access-Control-Allow-Origin': '*' });
let options = new RequestOptions({headers: headers});
let formData = new FormData();
formData.append("logo",file);
formData.append("org", new Blob([JSON.stringify(organization)],
{
type: "application/json"
}));
return this.http.post(AppSettings.API_ENDPOINT + "org", organization, options).map((response) => {
return;
})
}
这里的问题在哪里?以及需要更正的地方。
请建议。
我以这种方式解决了这个问题:
我们需要在XMLHttpRequest中设置我们的请求正文
Observable.fromPromise(new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
// setting the params
formData.append("logo",file);
formData.append("org", new Blob([JSON.stringify(organization)],
{
type: "application/json"
}));
// call post API method
xhr.open("POST", API_URL , true);
xhr.send(formData)
}));
如果任何其他聪明的方法,请随时建议。
由于您熟悉使用 XHR,因此下面是一个更高级的实现,其中包含上传堕胎和进度计数器。我们不使用 Promise
我们使用Observable
uploadFile(url: string, file: File, metadata?: any): Observable<string | number> {
// Initiates a FormData object to be sent to the server
const fd: FormData = new FormData()
fd.append('file', file)
// In case you want to add other fields to the `FormData`
if (metadata) {
for (const key in metadata) {
if (metadata.hasOwnProperty(key)) {
fd.append(key, metadata[key])
}
}
}
const xhr = new XMLHttpRequest
return Observable.create(observer => {
// Count progress of upload
xhr.upload.onprogress = (progress) => {
let percentCompleted
if (progress.lengthComputable) {
percentCompleted = Math.round(progress.loaded / progress.total * 100)
if (percentCompleted < 1) {
observer.next(0)
} else {
observer.next(percentCompleted)
}
}
}
xhr.onload = (e) => {
if (e.target['status'] !== 200) {
observer.error(e.target['responseText'])
} else {
observer.next(e.target['responseText'])
observer.complete()
}
}
xhr.onerror = () => {
observer.error('Upload error')
}
xhr.onabort = () => {
observer.error('Transfer aborted by the user')
}
xhr.open('POST', API_DOMAIN + url)
xhr.setRequestHeader('Authorization', `Bearer ${someAuthToken}`)
// Send the FormData
xhr.send(fd)
// Allows to abort file transfer on unsubscription
// sub.unsubscribe() <- will abort upload if not yet completed
return () => xhr.abort()
})
}
用法:
uploadRef;
upload() {
this.uploadRef = uploadFile('media/upload', someFileFromInputElement, {file_name: 'avatar.jpeg'}).subscribe(progress => {
if (typeof progress === 'number') {
console.log('upload progress', progress)
if (progress === 100) alert('Upload complete!')
}
})
}
// Abort upload
cancelUpload(): void {
if (this.uploadRef) this.uploadRef.unsubscribe()
}