Angular 前端 Spring 后端文件下载不工作或损坏

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

我有一些文件 (.odt) 存储在我尝试下载的 mysql 数据库中

Spring 后端(不是 Spring boot): 控制器:

@RequestMapping(value = "/downloadRequest", method = RequestMethod.GET)
    public ResponseEntity<Resource> downloadRequest(@RequestParam(value="id") int id) throws JsonProcessingException {
        try {
            byte [] fileData = getDocumentRestService().downloadRequest(id);
            
            Resource inputStreamResource = new InputStreamResource(new ByteArrayInputStream(fileData));
        
            HttpHeaders headers = new HttpHeaders();
            headers.setContentLength(fileData.length);
            headers.set(HttpHeaders.CONTENT_TYPE, "application/vnd.oasis.opendocument.text");
            headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + inputStreamResource.getFilename() + "\"");
            
            ResponseEntity<Resource> responseEntity = ResponseEntity.ok().headers(headers).body(inputStreamResource);
            return responseEntity;
        } catch (Exception e) {
            return null;
        }
    }

角度: 成分:

download() {
        let id: number = this.documentDetailFormGroup.controls['id'].value;

        if(id > 0) {
            this.documentDatasource.downloadFormData(id).subscribe(data => {
                let fileData = [];
                fileData.push(data.body);


                let downloadLink = document.createElement('a');
                downloadLink.href = window.URL.createObjectURL(new Blob(data, { type: 'application/vnd.oasis.opendocument.text' }));
                downloadLink.download = "Test.odt";
                document.body.appendChild(downloadLink);
                downloadLink.click();
                document.body.removeChild(downloadLink);
            });
        }
    }

通用数据源:

downloadFormData(id: number): Observable<any> {
        return this.ssBaseRequestService.sendDownloadRequestWithParams("GET", this.requestMapping + "/downloadRequest", this.ssBaseRequestService.httpParams(id));
    }

请求服务:

public sendDownloadRequestWithParams(method: string, url: string, params?: HttpParams): Observable<any> {
       return this.httpClient.get(this.backend_url + url, {params: params, observe: 'response', responseType: 'blob'});
    }

对于 Spring,我已经尝试使用 Jackson 返回 byte[]、Response 和 json 响应:

//     console.log(data.dto.fileData);
                //     var buf = Buffer.from(data.dto.fileData, 'base64').toString('utf8');
                //     console.log(buf);
                //     //console.log(atob(data.dto.fileData));
                //     let fileData = [];
                // //    let fileData = new Blob(atob(data.dto.fileData), { type: data.dto.contentType });
                //    fileData.push(buf);
                //     // console.log(fileData);

对于 Angular 我也尝试返回:

Observable<Blob> 

似乎没有任何效果。
.odt 文件为空或 .odt 文件包含 [Object object],有时无法在 Libreoffice 中打开(已损坏)

后端的byte[]包含一些负数,在前端被转换为正数(+256),导致被破坏?

有人知道我做错了什么吗?

还尝试过: Angular Spring Boot 文件下载

angular spring libreoffice openoffice.org
1个回答
0
投票

找了几天我想我终于找到了问题所在。 在后端,我正在做的是转换 blob:

public static byte[] convertBlobToBytes(Blob blob) {
        if(blob == null) {
            throw new ServiceException("exists.not", new String[] {"file"});
        }
        
        try {
            StringWriter stringWriter = new StringWriter();
            IOUtils.copy(blob.getBinaryStream(), stringWriter, Encoding.UTF_8);
            return stringWriter.toString().getBytes();
        } catch (SQLException e) {
            throw new ServiceException("exists.not", new String[] {"file"});
        } catch (IOException e) {
            throw new ServiceException("filecopy.failed");
        }
    }

我将其替换为:

public static byte[] convertBlobToBytes1(Blob blob) {
        if(blob == null) {
            throw new ServiceException("exists.not", new String[] {"file"});
        }
        
        try {
            return blob.getBytes(1, (int)blob.length());
        } catch (SQLException e) {
            throw new ServiceException("exists.not", new String[] {"file"});
        }
    }

这似乎可以解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.