I'm using Spring boot and Angular JS . I have a Spring REST Controller that I use to download a File. when I call it using http://localhost:8080/download it works and the file is downloaded. Now I have a button ,when I click on it , I the file will be downloaded . so I wrote a function in my angular js controller to get the url of my spring web service but when I tested it nothing happened . what should I do to fix this ? Is there a better way to download files using Spring and 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();
}
my angular js function ( I added console.log("ok") to see if I get a result from the spring controller and it printed ok )
$scope.downloadFile = function () {                   
        $http({method: 'GET', url: '/download'}).
         success(function(result) {
                        console.log("ok");
          }).
     error(function(data, status, headers, config) {
            console.log("oops");
         });
 };
and my button
<button  class="btn btn-success" ng-click="downloadFile()">download</button>
                It's working for me :
Spring controller : 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 Service :  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 config : app.js 
(function() {
    'use strict';
    var myApp = angular.module('myApp', ['components.donwload']);
   /* myApp.config([function () {
    }]);
    myApp.run([function () {
    }]);*/
})();
AngularJs controller : 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>
You are not able to download file because Angular is Expecting a JSON response.
You have to tell Angular that you are going to receive ArrayBuffer in response.
$http.post('Api/DownloadURL',$scope.data,{responseType:'arraybuffer'})
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With