web-dev-qa-db-fra.com

télécharger un fichier en utilisant Angular JS et un service Web RESTful basé sur Spring

J'utilise Spring boot et Angular JS. J'ai un contrôleur Spring REST que j'utilise pour télécharger un fichier. quand je l'appelle en utilisant http: // localhost: 8080/download cela fonctionne et le fichier est téléchargé. Maintenant, j'ai un bouton, quand je clique dessus, le fichier sera téléchargé. J'ai donc écrit une fonction dans mon contrôleur angulaire js pour obtenir l'URL de mon service Web Spring, mais rien ne s'est passé lorsque j'ai testé. Que dois-je faire pour résoudre ce problème? Existe-t-il un meilleur moyen de télécharger des fichiers en utilisant Spring et 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();

}

ma fonction js angulaire (j’ai ajouté console.log ("ok") pour voir si j’obtenais un résultat du contrôleur à ressort et le résultat était ok)

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

et mon bouton

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

Cela fonctionne pour moi:

  • Contrôleur à ressort: 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);
            }
    
        }
    
    }
    
  • Service 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;
                    }
                };
            }
        ]);
    })();
    
  • Configuration AngularJs: app.js

    (function() {
        'use strict';
    
        var myApp = angular.module('myApp', ['components.donwload']);
       /* myApp.config([function () {
    
        }]);
        myApp.run([function () {
    
        }]);*/
    
    
    })();
    
  • Contrôleur 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>
    
4
scoom

Vous ne pouvez pas télécharger le fichier car Angular attend une réponse JSON. Vous devez dire à Angular que vous allez recevoir ArrayBuffer en réponse.

$http.post('Api/DownloadURL',$scope.data,{responseType:'arraybuffer'})
3
Paras

J'ai résolu ce problème en utilisant les éléments suivants:

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

et appelez getReport() en utilisant ng-click à partir de votre page HTML.

0
Ahmed Tawila