java - 使用 ANGULARJS 从 Jersey Rest api 调用下载/保存文件。文件附有响应 "Content-Disposition"

标签 java angularjs rest csv jersey

我是 Angular 新手..我有 java Rest api,它返回 CSV 文件作为附件作为 | “内容处置”,“附件;文件名=” |内容类型:应用程序/八位字节流

现在,当我使用 $http 从 AngularJS 调用此 api 时,我得到了 response.data =""(空白)

为了安全起见,我使用基本授权,因此在调用 API 时必须传递 header ,因此无法使用链接点击或打开新窗口来下载 CSV。

测试我何时删除授权并在浏览器中点击 URL,然后下载 CSV 文件。因此服务器端没有问题。

我需要 angularjs 方面的帮助来从 Web api 响应下载 CSV 文件作为附件。

这是我的 Java API 代码

public class ServiceAPI {

@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getFileAsCSVFile(){

byte[] file=null;
    try {
        ArrayList<> List=new ArrayList<>();// data retrieved from DB 

        if(null != List){
             file=convertJsonToCSV(new Gson().toJson(List));

        }

    } catch (ParseException e) {


        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    return            Response.ok(getBytes(file),MediaType.APPLICATION_OCTET_STREAM).header("Content-Disposition", "attachment; filename=" + "FileName.csv").build();
 }
 }

和 Angular 代码:

app.controller('review', ['$scope', '$http',  function ($scope, $http){



$scope.fromDate = new Date();
$scope.toDate = new Date();


$scope.minDate = new Date(
    $scope.fromDate.getFullYear(),
    $scope.fromDate.getMonth() - 2,
    $scope.fromDate.getDate(),

    $scope.toDate.getFullYear(),
    $scope.toDate.getMonth() - 2,
    $scope.toDate.getDate()
);

$scope.maxDate = new Date(
    $scope.fromDate.getFullYear(),
    $scope.fromDate.getMonth() - 2,
    $scope.fromDate.getDate(),

    $scope.toDate.getFullYear(),
    $scope.toDate.getMonth() - 2,
    $scope.toDate.getDate()
);

$scope.reviews = json;


function openSaveAsDialog(filename, content, mediaType) {
    var blob = new Blob([content], {type: mediaType});
    saveAs(blob, filename);
}

function callApi(url) {

   // var dat=apiFactory.getServiceData(url);
   // console.log(dat);
   // apiFactory.getServiceData(url);

    var responseType='arraybuffer';
    var expectedMediaType='application/octet-stream';
    $http.get(url, {

        headers: {

            accept: expectedMediaType
        },
        responseType:responseType,
        cache: true,
        transformResponse: function (data) {
            var pdf;
            if (data) {
                pdf = new Blob([data], {
                    type: expectedMediaType
                });
            }
            return {
                response: pdf
            };
        }
    }).then(function (data,status,headers) {
        var filename='Preview.csv',
            octetStreamMime = "application/octet-stream",
            contentType;

        headers = data.headers();
        contentType = headers["content-type"] || octetStreamMime;


     //   openSaveAsDialog(filename, response.data, expectedMediaType);
        if (navigator.msSaveBlob) {
            var blob = new Blob([data], { type: contentType });
            navigator.msSaveBlob(blob, filename);
        } else {
            var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;

            if (urlCreator) {
                // Try to use a download link
                var link = document.createElement("a");

                if ("download" in link) {
                    // Prepare a blob URL
                    var blob = new Blob([data.data], { type: contentType });
                    var url = urlCreator.createObjectURL(blob);

                    link.setAttribute("href", url);
                    link.setAttribute("download", filename);

                    // Simulate clicking the download link
                    var event = document.createEvent('MouseEvents');
                    event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
                    link.dispatchEvent(event);
                } else {
                    // Prepare a blob URL
                    // Use application/octet-stream when using window.location to force download
                    var blob = new Blob([data], { type: octetStreamMime });
                    var url = urlCreator.createObjectURL(blob);
                    $window.location = url;
                }
            }
        }
    });

};
    $scope.submit = function (fromDate, toDate) {


       $scope.url = API_url;


        var resp =callApi(($scope.url).split(" ").join("%20"));

        console.log(resp);
    };
},
]);

最佳答案

我有一个使用 spring MVC 而不是 JAX-RS (Jersey) 的示例

HTML:

<button ng-click="downloadPdf()" class="btn btn-primary">download PDF</button>

Angularjs Controller :

$scope.downloadCsv = function () {
    console.log("downloadCsv");
    var fileName = "test.csv";
    var a = document.createElement("a");
    document.body.appendChild(a);
    XxxxxxServiceCSV.downloadCsv().then(function (result) {
        console.log("downloadCsv callback");
        var file = new Blob([result.data], {type: 'application/csv'});
        var fileURL = URL.createObjectURL(file);
        a.href = fileURL;
        a.download = fileName;
        a.click();
    });
};

Angularjs 服务:

angular.module('xxxxxxxxApp')
    .factory('XxxxxxServiceCSV', function ($http) {
        return {
            downloadCsv: function () {
            return $http.get('api/downloadCSV', { responseType: 'arraybuffer' }).then(function (response) {
                return response;
            });
        }
    };
});

Java代码JAX-RS(spring MVC):

@RequestMapping(value = "/downloadCSV", method = RequestMethod.GET, produces = "application/csv")
public void demo(HttpServletResponse response) throws IOException {
    List<String> names = new ArrayList<String>();
    names.add("First Name");
    names.add("Second Name");
    names.add("Third Name");
    names.add("Fourth Name");
    BufferedWriter writer = new BufferedWriter(response.getWriter());
    try {
        response.setHeader("Content-Disposition", "attachment; filename=\"test.csv\"");
        for (String name : names) {
            writer.write(name);
            writer.write(",");
        }
        writer.newLine();
    } catch (IOException ex) {
    } finally {
        writer.flush();
        writer.close();
    }
}

关于java - 使用 ANGULARJS 从 Jersey Rest api 调用下载/保存文件。文件附有响应 "Content-Disposition",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33244766/

相关文章:

javascript - 在我的 ng-repeat 中看不到预期的数据

javascript - 在 angular-ui 中手动输入文本

php - 为 rest api 传输用户密码

python - 如何考虑 Django 的普通基于类的 View 与使用 REST API

JavaCC语法问题,具有理解能力

java - fireTableStructureChanged 后如何在 JTable 中维护用户指定的表行排序?

javascript - highcharts-ng ajax 数据加载

java - JAX-RS 接受图像作为输入

java - 单线程执行的性能调优

Java从.bin文件转换为.txt加载