打字稿:将文件数据加载为Blob

时间:2019-01-19 18:30:50

标签: angular typescript swagger-codegen

我正在尝试以angular7 / typescript加载文件,以实现以下功能:

public add3dModel(input?: Blob, observe?: 'body', reportProgress?: boolean): Observable<string>;
public add3dModel(input?: Blob, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<string>>;
public add3dModel(input?: Blob, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<string>>;
public add3dModel(input?: Blob, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {

    let headers = this.defaultHeaders;

    // authentication (oauth) required
    if (this.configuration.accessToken) {
        let accessToken = typeof this.configuration.accessToken === 'function'
            ? this.configuration.accessToken()
            : this.configuration.accessToken;
        headers = headers.set('Authorization', 'Bearer ' + accessToken);
    }

    // to determine the Accept header
    let httpHeaderAccepts: string[] = [
        'application/json'
    ];
    let httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
    if (httpHeaderAcceptSelected != undefined) {
        headers = headers.set("Accept", httpHeaderAcceptSelected);
    }

    // to determine the Content-Type header
    let consumes: string[] = [
        'multipart/form-data'
    ];

    const canConsumeForm = this.canConsumeForm(consumes);

    let formParams: { append(param: string, value: any); };
    let useForm = false;
    let convertFormParamsToString = false;
    // use FormData to transmit files using content-type "multipart/form-data"
    // see https://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data
    useForm = canConsumeForm;
    if (useForm) {
        formParams = new FormData();
    } else {
        formParams = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()});
    }

    if (input !== undefined) {
        formParams = formParams.append('input', <any>input) || formParams;
    }

    return this.httpClient.put<string>(`${this.basePath}/backend/model`,
        convertFormParamsToString ? formParams.toString() : formParams,
        {
            withCredentials: this.configuration.withCredentials,
            headers: headers,
            observe: observe,
            reportProgress: reportProgress
        }
    );
}

此功能是使用swagger-codegen自动输入的。

我正在使用的HTML:

<input type="file" (change)="get3DModel($event)">

这是在更改时调用的函数:

get3DModel(e) {
  this._3dmodel_local = e.target.files[0];
}

现在按下按钮后(有效),我想使用add3dModel功能上传所选文件。

我为此尝试过的代码(在按钮的功能内):

  var r = new FileReader();
  r.onload = (e) =>{
    this.add3dModel(r.result) //obviously doesn't work
  }
  r.readAsArrayBuffer(this._3dmodel_local);

this.add3dModel(this._3dmodel_local);

服务器两次都返回带有内部消息400 Bad Request的{​​{1}}

我在做什么错了?

为了澄清:我的目标是加载本地文件并将其上传到服务器。

以下是后端源代码,它是一个Spring-boot项目。

自动生成的API代码

No file present

儿童班:

@ApiOperation(value = "add new 3D Model", nickname = "add3dModel", notes = "", response = String.class, authorizations = {
    @Authorization(value = "oauth", scopes = {
        @AuthorizationScope(scope = "admin", description = "admin rights")
        })
}, tags={ "glassesBackend", })
@ApiResponses(value = { 
    @ApiResponse(code = 201, message = "created", response = String.class),
    @ApiResponse(code = 400, message = "bad request"),
    @ApiResponse(code = 401, message = "unauthorized"),
    @ApiResponse(code = 404, message = "not found") })
@ApiImplicitParams({
})
@RequestMapping(value = "/backend/model",
    produces = { "application/json" }, 
    consumes = { "multipart/form-data" },
    method = RequestMethod.PUT)
default ResponseEntity<String> add3dModel(@ApiParam(value = "file detail") @Valid @RequestPart("file") MultipartFile input) {
    return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);

}

在甚至遇到 @Override public ResponseEntity<String> add3dModel(@Valid MultipartFile formData){ return ResponseEntity.ok(service.add3dModel(formData)); //using JPA repository } 方法之前,我遇到以下错误:

add3dModel

1 个答案:

答案 0 :(得分:0)

我创建了一个stackblitz示例,其中输入类型=文件有效,样本中唯一缺少的就是上传请求。尝试构建您的请求对象this way

如果后端正在等待multipart/form-data,则必须将其用作Content-Type而不是application/json。不要忘记在请求标头中附加您的Authorization令牌:

let fileList: FileList = event.target.files;
if(fileList.length > 0) {
    let file: File = fileList[0];
    let formData:FormData = new FormData();
    formData.append('uploadFile', file, file.name);
    let headers = new Headers();
    /** In Angular 5, including the header Content-Type can invalidate your request */

    headers.append('Content-Type', 'multipart/form-data');
    headers.append('Accept', 'application/json');
    headers.append('Authorization', 'Bearer ' + accessToken);

    let options = new RequestOptions({ headers: headers });
    this.http.post(`${this.apiEndPoint}`, formData, options)
        .map(res => res.json())
        .catch(error => Observable.throw(error))
        .subscribe(
            data => console.log('success'),
            error => console.log(error)
        )
}