使用 Angular2 将文件上传到 REST API [英] File Upload with Angular2 to REST API

查看:29
本文介绍了使用 Angular2 将文件上传到 REST API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

实际上,我正在开发一个带有以 Angular 2 编码的接口的 Spring REST API.

Actually, I'm working on a Spring REST API with an interface coded in Angular 2.

我的问题是我无法使用 Angular 2 上传文件.

My problem is I can't upload a file with Angular 2.

我在 Java 中的 Webresources 是:

My Webresources in java is that :

@RequestMapping(method = RequestMethod.POST, value = "/upload")
public String handleFileUpload(@RequestParam MultipartFile file) {
    //Dosomething 
}

当我通过带有 Auth 标头等的 URL 请求调用它时,它完美地工作......(带有适用于 Chrome 的 Advanced Rest Client 扩展)

And it is perfectly working when I call it through URL request with Auth header etc ... ( with Advanced Rest Client extension for Chrome )

证明:(在那种情况下一切正常)

Proof: (everything works fine in that case )

我添加了

<bean id="multipartResolver"
      class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />

Spring 配置文件和 Pom 依赖

Spring config file and the Pom dependency

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.2</version>
</dependency>

但是当我尝试使用网络表单做同样的事情时:

BUT when I try to do the same thing with a webform :

<input type="file" #files (change)="change(files)"/>
<pre>{{fileContents$|async}}</pre>

使用(更改)方法:

change(file) {
    let formData = new FormData();
    formData.append("file", file);
    console.log(formData);
    let headers = new Headers({
        'Authorization': 'Bearer ' + this.token,
        'Content-Type': 'multipart/form-data'
    });
    this.http.post(this.url, formData, {headers}).map(res => res.json()).subscribe((data) => console.log(data));
    /*
    Observable.fromPromise(fetch(this.url,
        {method: 'post', body: formData},
        {headers: this.headers}
    )).subscribe(()=>console.log('done'));
    */
}

我的网络服务返回一个错误 500,在 tomcat 日志中:http://pastebin.com/PGdcFUQb

My web service returns me an error 500, with that in tomcat logs: http://pastebin.com/PGdcFUQb

我也尝试了 'Content-Type': undefined 方法,但没有成功(在这种情况下,Web 服务返回 415 错误.

I tried the 'Content-Type': undefined method too but without success ( the web service return me a 415 error in that case.

谁能帮我找出问题所在?

Can someone help me to figure out what's the problem is?

问题解决了,我稍后会用我的代码更新这个问题:) 但是,看看 plunker,它运行得非常好.谢谢.

Problem solved, I'll update that question later with my code :) but, have a look on the plunker it's working perfectly well. Thanks.

推荐答案

这实际上在最终版本中很容易做到.我花了一些时间来理解它,因为我遇到的大多数关于它的信息都已经过时了.在这里发布我的解决方案,以防其他人遇到此问题.

This is actually really easy to do in the final release. Took me a while to wrap my head around it because most information about it that I've come across is outdated. Posting my solution here in case anyone else is struggling with this.

import { Component, ElementRef, Input, ViewChild } from '@angular/core';
import { Http } from '@angular/http';

@Component({
    selector: 'file-upload',
    template: '<input type="file" [multiple]="multiple" #fileInput>'
})
export class FileUploadComponent {
    @Input() multiple: boolean = false;
    @ViewChild('fileInput') inputEl: ElementRef;

    constructor(private http: Http) {}

    upload() {
        let inputEl: HTMLInputElement = this.inputEl.nativeElement;
        let fileCount: number = inputEl.files.length;
        let formData = new FormData();
        if (fileCount > 0) { // a file was selected
            for (let i = 0; i < fileCount; i++) {
                formData.append('file[]', inputEl.files.item(i));
            }
            this.http
                .post('http://your.upload.url', formData)
                // do whatever you do...
                // subscribe to observable to listen for response
        }
    }
}

然后像这样使用它:

<file-upload #fu (change)="fu.upload()" [multiple]="true"></file-upload>

这就是它的全部.

或者,捕获事件对象并从 srcElement 获取文件.老实说,不确定任何一种方式是否比另一种方式更好!

Alternatively, capture the event object and get the files from the srcElement. Not sure if any way is better than the other, to be honest!

请记住,FormData 是 IE10+,因此如果您必须支持 IE9,则需要一个 polyfill.

Keep in mind FormData is IE10+, so if you have to support IE9 you'll need a polyfill.

更新 2017-01-07

更新了代码以能够处理多个文件的上传.此外,我的原始答案还缺少关于 FormData 的一个相当关键的部分(因为我将实际上传逻辑移到我自己的应用程序中的单独服务中,我在那里处理它).

Updated code to be able to handle uploading of multiple files. Also my original answer was missing a rather crucial bit concerning FormData (since I moved the actual upload logic to a separate service in my own app I was handling it there).

这篇关于使用 Angular2 将文件上传到 REST API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆