스프링 - 응답을 파일로 다운로드
Angular Angular를 사용해서 원서를 .JS 봄 。해, 하고 싶습니다.서버에 요청을 보내고 컨트롤러에서 반환된 응답을 파일로 다운로드하고 싶습니다. 파일 csv 파일(문자열)은 csv 파일(문자열)로 되어 .1;2;3;4
(1피트, 4피트).이 응답을 파일로 다운로드하는 가장 간단한 방법은 무엇입니까?
아래에 간략화된 코드를 올렸습니다.스프링 컨트롤러:
@RequestMapping(value = "/csv", method = GET)
@ResponseBody
public String getCsvFile() {
return getCsvContent();
}
javascript(각도)JS)
return $http({method: 'GET', url: 'csv/'});
응답 스트림에도 쓰려고 했는데(아래), 헤더를 설정하고 있었는데 클라이언트 측에서는 항상 이 콘텐츠를 다운로드 파일이 아닌 문자열로 받습니다.
@RequestMapping(value = "/csv", method = GET)
@ResponseBody
public void getCsvFile(HttpServletResponse response) {
response.setContentType("application/csv");
response.setHeader("Content-Disposition", "attachment; filename=file.csv");
response.setContentLength(getCsvContent().getBytes().length);
ServletOutputStream out = response.getOutputStream();
out.write(getCsvContent());
out.flush();
out.close();
}
클라이언트 측에서 응답을 파일로 다운로드하기 위해 컨트롤러의 메서드를 올바르게 쓰는 방법을 아는 사람이 있습니까?
XHR 요청(즉, Angular가 요청을 만드는 방법)을 통해 파일을 다운로드할 수 없습니다.자세한 내용은 Ajax 요청을 사용하여 파일을 다운로드할 수 없는 이유를 참조하십시오.다음 URL로 이동해야 합니다.$window.open
또는 JSON 데이터를 사용하여 POST를 통해 파일을 다운로드하는 JavaScript/jQuery를 실행합니다.
내가 직접 이 문제를 해결하려고 노력했어.할 수 없었다.대신...
@는, @dnc253 를 참조해 .
$window.open(URL)
는 Angular 어플리케이션이 다른 창에서 특정 URL을 열도록 하는 방법입니다.(이것은 실제로는 범용에 대한 테스트 가능한 각도 프록시일 뿐입니다.window.open()
이는 뛰어난 솔루션이며, 이력을 보존하고 파일을 다운로드하여 새로운 브라우저 창에서 렌더링할 수 있습니다(지원되는 경우).그러나 팝업 차단에 부딪히는 경우가 많아 신뢰성에 큰 문제가 됩니다.사용자는 자신의 상태를 이해하지 못하는 경우가 많습니다.따라서 현재 창에서 파일을 즉시 다운로드하는 것이 괜찮다면 동일한 효과의 범용 javascript 방식을 사용할 수 있습니다.location.href = "uriString"
무슨 있어합니다.POST/PUT를 사용합니다.필요에 따라서, 아직 추측할 수 없는 경우는, POST/PUT 에 문의할 URL 를 반환합니다.PUT/POST에 대한 응답으로 다운로드 받은 것과 동일한 동작을 사용자에게 제공합니다.를 들면, '먹다'와 같이요.$http.post(url, payload).then(function(returnData){ var uriString = parseReturn(returnData); location.href="uriString" })
실제로 XHR 요청에서 직접 다운로드 할 수 있지만 HTML5 파일 API를 완전히 지원해야 하며, 사용자가 파일을 사용할 수 있도록 하기 전에 로컬 변환을 수행할 필요가 없는 한 보통 문제보다 더 큰 문제가 발생합니다.(슬프게도 자세한 내용을 제공할 시간은 없지만 다른 게시물이 있습니다.)사용할 수 없습니다.)
XHR 요청을 사용하여 파일을 다운로드할 수 있습니다.angular $http를 사용하여 파일을 로드한 후 HTML5의 Blob 기능을 사용하여 브라우저로 파일을 저장할 수 있습니다.저장에 도움이 되는 라이브러리가 있습니다.파일 세이버.js.
필요한 경우 다음 링크를 참고하십시오.
건배.
코드 샘플을 이해하기 위해 아래에 코멘트를 작성했습니다.어떤 것은 사용한다면, 내가 파일 이름을 붙여줬기 때문에 그들은 그것을 따라갈 수 있다.
서버가 응답으로 blob을 송신하고 있는 경우, 클라이언트는 그것을 생성할 수 있습니다.
이것을 사용하면 나의 목적이 해결되기 때문에.모든 파일에 「application/*」를 사용하고 있기 때문에, 파일을 다운로드할 수 있습니다.
작성된 "downloadLink" 변수는 응답에 사용되는 기술일 뿐이며, 링크에 클릭된 것처럼 채워지면 응답이 오고 그 href가 트리거됩니다.
controller.js
//this function is in controller, which will be trigered on download button hit.
$scope.downloadSampleFile = function() {
//create sample hidden link in document, to accept Blob returned in the response from back end
var downloadLink = document.createElement("a");
document.body.appendChild(downloadLink);
downloadLink.style = "display: none";
//This service is written Below how does it work, by aceepting necessary params
downloadFile.downloadfile(data).then(function (result) {
var fName = result.filename;
var file = new Blob([result.data], {type: 'application/*'});
var fileURL = (window.URL || window.webkitURL).createObjectURL(file);
//Blob, client side object created to with holding browser specific download popup, on the URL created with the help of window obj.
downloadLink.href = fileURL;
downloadLink.download = fName;
downloadLink.click();
});
};
services.js
.factory('downloadFile', ["$http", function ($http) {
return {
downloadfile : function () {
return $http.get(//here server endpoint to which you want to hit the request
, {
responseType: 'arraybuffer',
params: {
//Required params
},
}).then(function (response, status, headers, config) {
return response;
});
},
};
}])
효과가 있습니다.
스프링 컨트롤러:
DownloadController.java
package com.mycompany.myapp.controller; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.mycompany.myapp.exception.TechnicalException; @RestController public class DownloadController { private final Logger log = LoggerFactory.getLogger(DownloadController.class); @RequestMapping(value = "/download", method = RequestMethod.GET) public void download(@RequestParam ("name") String name, final HttpServletRequest request, final HttpServletResponse response) throws TechnicalException { log.trace("name : {}", name); File file = new File ("src/main/resources/" + name); log.trace("Write response..."); try (InputStream fileInputStream = new FileInputStream(file); OutputStream output = response.getOutputStream();) { response.reset(); response.setContentType("application/octet-stream"); response.setContentLength((int) (file.length())); response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\""); IOUtils.copyLarge(fileInputStream, output); output.flush(); } catch (IOException e) { log.error(e.getMessage(), e); } } }
AngularJs 서비스:
download.service.js
(function() { 'use strict'; var downloadModule = angular.module('components.donwload', []); downloadModule.factory('downloadService', ['$q', '$timeout', '$window', function($q, $timeout, $window) { return { download: function(name) { var defer = $q.defer(); $timeout(function() { $window.location = 'download?name=' + name; }, 1000) .then(function() { defer.resolve('success'); }, function() { defer.reject('error'); }); return defer.promise; } }; } ]); })();
AngularJs 구성:
app.js
(function() { 'use strict'; var myApp = angular.module('myApp', ['components.donwload']); /* myApp.config([function () { }]); myApp.run([function () { }]);*/ })();
AngularJs 컨트롤러:
download.controller.js
(function() { 'use strict'; angular.module('myApp') .controller('DownloadSampleCtrl', ['downloadService', function(downloadService) { this.download = function(fileName) { downloadService.download(fileName) .then(function(success) { console.log('success : ' + success); }, function(error) { console.log('error : ' + error); }); }; }]); })();
index.html
<!DOCTYPE html> <html ng-app="myApp"> <head> <title>My App</title> <link rel="stylesheet" href="bower_components/normalize.css/normalize.css" /> <link rel="stylesheet" href="assets/styles/main.css" /> <link rel="icon" href="favicon.ico"> </head> <body> <div ng-controller="DownloadSampleCtrl as ctrl"> <button ng-click="ctrl.download('fileName.txt')">Download</button> </div> <script src="bower_components/angular/angular.min.js"></script> <!-- App config --> <script src="scripts/app/app.js"></script> <!-- Download Feature --> <script src="scripts/app/download/download.controller.js"></script> <!-- Components --> <script src="scripts/components/download/download.service.js"></script> </body> </html>
//JAVA 부품
@RequestMapping(value = "/report-excel", method = RequestMethod.GET)
public ResponseEntity<byte[]> getReportExcel(@RequestParam("bookingStatusType") String bookingStatusType,
@RequestParam("endDate") String endDate, @RequestParam("product") String product, @RequestParam("startDate") String startDate)throws IOException, ParseException {
//Generate Excel from DTO using any logic after that do the following
byte[] body = wb.getBytes();
HttpHeaders header = new HttpHeaders();
header.setContentType(new MediaType("application", "xlsx"));
header.set("Content-Disposition", "inline; filename=" + fileName);
header.setCacheControl("must-revalidate, post-check=0, pre-check=0");
header.setContentLength(body.length);
return new ResponseEntity<byte[]>(body, header, HttpStatus.OK);
}
//HTML PART
<html>
<head>
<title>Test</title>
<meta http-equiv="content-type" content="application/x-www-form-urlencoded; charset=UTF-8">
</head>
<body>
<form name="downloadXLS" method="get" action="http://localhost:8080/rest/report-excel" enctype="multipart/form-data">
<input type="text" name="bookingStatusType" value="SALES"></input>
<input type="text" name="endDate" value="abcd"></input>
<input type="text" name="product" value="FLIGHT"></input>
<input type="text" name="startDate" value="abcd"></input>
<input onclick="document.downloadXLS.submit()" value="Submit"></input>
</form>
</body>
</html>
언급URL : https://stackoverflow.com/questions/17177303/spring-download-response-as-a-file
'code' 카테고리의 다른 글
WordPress 디버깅 (0) | 2023.03.14 |
---|---|
panda read_json: "모든 스칼라 값을 사용하는 경우 인덱스를 통과해야 합니다." (0) | 2023.03.14 |
camel-jackson을 사용하여 JSONArray를 List of Object로 변환하는 방법 (0) | 2023.03.14 |
모델 세트를 폼 데이터에 추가하여 MVC에서 얻는 방법 (0) | 2023.03.14 |
ng-if를 사용하여 변수가 정의되어 있는지 테스트하는 방법 (0) | 2023.03.14 |