8

我正在使用 Spring boot 和 Angular JS 。我有一个用于下载文件的 Spring REST 控制器。当我使用http://localhost:8080/download调用它时,它可以工作并下载文件。现在我有一个按钮,当我点击它时,我将下载文件。所以我在我的 Angular js 控制器中编写了一个函数来获取我的 Spring Web 服务的 url,但是当我测试它时什么也没发生。我该怎么做才能解决这个问题?有没有更好的方法来使用 Spring 和 Angular 下载文件?

 /**
 * Size of a byte buffer to read/write file
 */
private static final int BUFFER_SIZE = 4096;
private String filePath = "C:\\Users\\marwa\\Desktop\\marwa\\gg.jpg";

/**
 * Method for handling file download request from client
 */
@RequestMapping (value="/download", method=RequestMethod.GET )
public void doDownload(HttpServletRequest request,
        HttpServletResponse response) throws IOException {

    // get absolute path of the application
    ServletContext context = request.getServletContext();
    String appPath = context.getRealPath("");
    System.out.println("filepath = " + filePath);

    // construct the complete absolute path of the file

    File downloadFile = new File(filePath);
    FileInputStream inputStream = new FileInputStream(downloadFile);

    // get MIME type of the file
    String mimeType = context.getMimeType(filePath);
    if (mimeType == null) {
        // set to binary type if MIME mapping not found
        mimeType = "application/octet-stream";
    }
    System.out.println("MIME type: " + mimeType);

    // set content attributes for the response
    response.setContentType(mimeType);
    response.setContentLength((int) downloadFile.length());

    // set headers for the response
    String headerKey = "Content-Disposition";
    String headerValue = String.format("attachment; filename=\"%s\"",
            downloadFile.getName());
    response.setHeader(headerKey, headerValue);

    // get output stream of the response
    OutputStream outStream = response.getOutputStream();

    byte[] buffer = new byte[BUFFER_SIZE];
    int bytesRead = -1;

    // write bytes read from the input stream into the output stream
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        outStream.write(buffer, 0, bytesRead);
    }

    inputStream.close();
    outStream.close();

}

我的 Angular js 函数(我添加了 console.log("ok") 以查看我是否从 spring 控制器获得结果并且打印正常)

$scope.downloadFile = function () {                   
        $http({method: 'GET', url: '/download'}).
         success(function(result) {
                        console.log("ok");
          }).
     error(function(data, status, headers, config) {
            console.log("oops");
         });
 };

和我的按钮

<button  class="btn btn-success" ng-click="downloadFile()">download</button>
4

3 回答 3

5

它对我有用:

  • 弹簧控制器: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>
    
于 2015-06-27T13:13:09.847 回答
4

您无法下载文件,因为 Angular 需要 JSON 响应。你必须告诉 Angular 你将收到ArrayBuffer回应。

$http.post('Api/DownloadURL',$scope.data,{responseType:'arraybuffer'})
于 2015-04-20T12:27:42.417 回答
0

我使用以下方法解决了这个问题:

$scope.getReport = function() {
    var downloadPath = 'your/spring/controller/address';
    window.open(downloadPath, '_blank', '');
}

并从您的 html 页面调用getReport()using 。ng-click

于 2017-03-25T10:49:53.133 回答