How to send a ByteArrayResource via ResponseEntity

2.3k Views Asked by At

I am working on a Java application, and the functionality I am working on is to download a file after populating it's content from the database when the user clicks on export button, the file is generated correctly, the problem I have is when I try to set ByteArrayResource into the ResponseEntity, when I call the webservice from angular, I get Byte array resource [resource loaded from byte array] cannot be resolved to absolute file path, here is my code :

Controller method :

  @GetMapping(value = "/exportods/{id}")
  public ResponseEntity<ExportDTO> exportODSFile(@PathVariable  String id)
      throws InvalidationRequestNotFoundException, IOException, ExportInvalidationRequestException {


    File odsFfile = null;
    ByteArrayResource resource = null;
    ExportInvalidationRequestDTO exportInvalidationRequestDTO = new ExportInvalidationRequestDTO();
    try {

      //getting the file
      odsFfile = exportService.exportInvalidationRequest(id);

      Path pathObj = Paths.get(odsFfile.getCanonicalPath());

      //creating the resource
      resource = new ByteArrayResource(Files.readAllBytes(pathObj));

      exportDTO.setResource(resource);

    } catch (IOException e) {
      exportDTO.setError(new ErrorDTO(HttpStatus.NOT_FOUND.value()));
    }

    return ResponseEntity.ok(exportDTO);
  }

ExportDTO :

public class ExportDTO extends AbstractReturnDTO {
  private ByteArrayResource resource;

  public ExportDTO (ByteArrayResource resource) {
    this.resource = resource;
  }

  public ExportDTO () {
  }

  public ByteArrayResource getResource() {
    return resource;
  }

  public void setResource(ByteArrayResource resource) {
    this.resource = resource;
  }
}

Angular component method:

async downloadODSFile(id) {
    await this.requestService.downloadODSFile(id).subscribe((requestExportODS: RequestExportODS) => {
        if (!requestExportODS) {
            if(requestExportODS.error == null){
                //handle error here
            }
           else{
                saveAs(new Blob([requestExportODS.file], { type: \'application/vnd.oasis.opendocument.spreadsheet\'' }), id );
            }
        }
    });
}

Once I click on the export button, I get an error :

error: "Internal Server Error"
message: "Byte array resource [resource loaded from byte array] cannot be resolved to absolute file path"
1

There are 1 best solutions below

1
Sameer On

Set the observe as response in the http service method

//requestService
downloadODSFile(id) {
 return this.http.get<HttpResponse<any>>(`/exportods/${id}`, { observe: 'response' })
}

And use it like this

async downloadODSFile(id) {
    await this.requestService.downloadODSFile(id).subscribe(res => {
        console.log(res.body) //Byte array
    });
}

BTW async and await are redundant in your code, as you haven't converted observable to promise.