Spring + Angular - 如何下载服务器生成的文件?

问题描述 投票:0回答:1

我的服务器上有一个端点,它应该返回一个即时生成的json文件。这是我写的。

    @GetMapping(value = "/{id}/json", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    @ApiOperation(value = "Animal data as a json file", authorizations = {@Authorization(value = "JWT")})
    public ResponseEntity<byte[]> getAnimalFile(@PathVariable("id") String id) throws JsonProcessingException {
       Animal animal = animalService.getAnimal(id);
       return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + animal.getId() + ".json").body(new ObjectMapper().writeValueAsBytes(animal));
    }

@ApiOperation允许swagger在生成我的客户端库时包含这个操作.然而,这就是ng-swagger-gen在Angular端生成的东西。

  /**
   * @param id id
   * @return OK
   */
  getAnimalFileUsingGET(id: string): __Observable<string> {
    return this.getAnimalFileUsingGETResponse(id).pipe(
      __map(_r => _r.body as string)
    );
  }

这并不理想,因为我不能通过这种方式下载服务器生成的文件。在我的组件中,我有一个exportJSON方法。

exportJSON(): void {
   this.animalService.getAnimalFileUsingGET(this.animal.id).subscribe(content => {
       console.log(content); // prints the json content but I don't have the filename
   });
}

我看了SO上的其他答案,他们说使用... window.open(SERVER_ENDPOINT_HERE) 但这行不通,因为我的端点使用的是认证(JWT)。

有没有一种方法可以或者。

  • 让ng -swagger -gen意识到这是一个带文件名的文件,并在我订阅Observable时提供给我这两个文件名
  • 还是绕过swagger,使用Angular使用服务器提供的文件名和认证来下载文件?

理想的解决方案是在服务器端改变一些东西,让swagger生成正确的响应类型,这样我就可以从服务器上获得文件和文件名。

angular spring swagger springfox
1个回答
1
投票

试试下面的方法。

 getAnimalFileUsingGET(id: string | number): Observable<Blob> {
    return this.http.get(`/stats/export/${id}`, {responseType: 'blob'}); // Adjust your GET accordingly
  }

另外,你还需要安装FileSaver.js。

npm i [email protected]

最后,像这样使用。

 import { saveAs } from 'file-saver';
 .
 .
 .
 .
 .

 exportJSON(): void {
     this.animalService.getAnimalFileUsingGET(this.animal.id).subscribe((blob: Blob) => {
       saveAs(blob, 'export.json');
     });
 }

EDIT 1:为了能够访问... Content-disposition 头,你需要指示Angular Http客户端在响应中做一些改变。

  getAnimalFileUsingGET(id: string | number): Observable<HttpResponse<any>> {
    return this.http.get(`/stats/export/${id}`, {observe: 'response', responseType: 'json' })
  }

然后你就可以像这样订阅了。

exportJSON(): void {
this.animalService.getAnimalFileUsingGET(this.animal.id).subscribe((resp: HttpResponse<Blob>) => {
           console.log(resp.headers.get('content-disposition'));
           // Extract filename from header
           const filename = '';
           saveAs(resp.body, filename);
   });
}
© www.soinside.com 2019 - 2024. All rights reserved.