code

스프링 - 응답을 파일로 다운로드

starcafe 2023. 3. 14. 21:47
반응형

스프링 - 응답을 파일로 다운로드

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를 실행합니다.

내가 직접 이 문제를 해결하려고 노력했어.할 수 없었다.대신...

  1. @는, @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"
    })
    
  2. 실제로 XHR 요청에서 직접 다운로드 할 수 있지만 HTML5 파일 API를 완전히 지원해야 하며, 사용자가 파일을 사용할 수 있도록 하기 전에 로컬 변환을 수행할 필요가 없는 한 보통 문제보다 더 큰 문제가 발생합니다.(슬프게도 자세한 내용을 제공할 시간은 없지만 다른 게시물이 있습니다.)사용할 수 없습니다.)

XHR 요청을 사용하여 파일을 다운로드할 수 있습니다.angular $http를 사용하여 파일을 로드한 후 HTML5의 Blob 기능을 사용하여 브라우저로 파일을 저장할 수 있습니다.저장에 도움이 되는 라이브러리가 있습니다.파일 세이버.js.

필요한 경우 다음 링크를 참고하십시오.

  1. angular js의 web api에서 csv 파일 다운로드
  2. 서버 상호 작용 없이 javascript 데이터를 CSV 파일로 내보내기

건배.

코드 샘플을 이해하기 위해 아래에 코멘트를 작성했습니다.어떤 것은 사용한다면, 내가 파일 이름을 붙여줬기 때문에 그들은 그것을 따라갈 수 있다.

  1. 서버가 응답으로 blob을 송신하고 있는 경우, 클라이언트는 그것을 생성할 수 있습니다.

  2. 이것을 사용하면 나의 목적이 해결되기 때문에.모든 파일에 「application/*」를 사용하고 있기 때문에, 파일을 다운로드할 수 있습니다.

  3. 작성된 "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

반응형