下载后JAR归档文件损坏:文件体积异常增大问题求助
问题:JAR文件下载后体积异常增大且损坏
我搭建了一个前后端文件浏览下载项目:后端基于Java开发,前端是Angular应用。后端暴露目录路径供前端访问,用户可通过前端浏览目录下文件。
目前大部分文件下载正常,但JAR归档文件下载后体积远大于原文件(比如原文件18MB,下载后变成30MB),导致文件损坏。奇怪的是,响应头的Content-Length和传输字节数都和预期文件大小一致(见附图)。我尝试为请求和响应设置application/java-archive MediaType,但问题仍未解决。
后端代码
/** Snippet by @fateddy * * @param path the path to the file as a String * @return a resource representing the file to download */ @GetMapping("/browsable/download") public ResponseEntity<Resource> getFile(@RequestParam (required = true) String path) { String pathToFile = ROOT_PATH + File.separator + path; Path pathTMP = Paths.get(pathToFile); // Temporary Path-Object File file = new File(pathToFile); HttpHeaders headers = new HttpHeaders(); MediaType mediatype = MediaType.APPLICATION_OCTET_STREAM; if (resolveFileExtension(file).equals(".jar")){ // custom mediaType for .jar files mediatype = MediaType.parseMediaType("application/java-archive"); } try { ByteArrayResource resource = new ByteArrayResource(Files.readAllBytes(pathTMP)); return ResponseEntity.ok() .headers(headers) .contentLength(file.length()) .contentType(mediatype) .body(resource); } catch (IOException e) { System.err.println("Something went wrong"); throw new RuntimeException(e); } }
前端调用代码
/** * The wrapper function for Requesting a file Download * Called by the HTMLElements of the "Files"-Part of the filebrowser * @param fileClicked the file which is to be downloaded */ requestFile(fileClicked: string) { if (this.currentURL === '') { var url = fileClicked; } else { var url = this.currentURL + this.pathSeperator + fileClicked; // The full URL of the Child directory } this.dl_filename = fileClicked; this.mediaType = 'application/octet-stream'; if (this.resolveFileExtension(fileClicked) == '.jar') { this.mediaType = 'application/java-archive'; // apply custom mediaType for .jar files } this.http .downloadFile(url, this.mediaType) .subscribe(this.observerDOWNLOAD); // Call the Server and download the file -> calls download() inside the Observer }
HttpService代码
/** * Calls the /download Endpoint to request a download of the given file * @param filePath The relative path to the file which was requested for Download * @returns An Observable containing the response of the Server (aka. the File as an Observable) */ downloadFile(filePath: string, mediaType: string) { var httpOptions = {}; httpOptions = { params: new HttpParams().set('path', filePath), responseType: mediaType }; const url = `${environment.serverUrl}/browsable/download`; const result = this.http.get(url, httpOptions); return result; }
下载处理代码
/** * Downloads the given file inside a newly-created, hidden, a-tag-HTMLElement, which is destroyed afterwards * Called by the Observer responsible for downloads * @param response an Observable representing the File */ download(response: any) { // Create a blob representing the File // "Blobs represent data that isn't necessarily in a JavaScript-native format." const blob = new Blob([response], { type: this.mediaType }); const url = window.URL.createObjectURL(blob); /** Workaround for FileDownload | Snippet customized from @Kol 1 - Create a hidden <a> tag. 2 - Set its href attribute to the blob's URL. 3 - Set its download attribute to the filename. 4 - Click on the <a> tag. */ var a = document.createElement('a'); document.body.appendChild(a); a.className = 'hidden'; a.href = url; a.download = this.dl_filename; a.click(); window.URL.revokeObjectURL(url); a.remove(); }
请求与响应截图

内容的提问来源于stack exchange,提问作者Sven Eckert
相关产品推荐
相关产品推荐

