使用 liferay ServeResource 下载文件到浏览器

Download a file to browser with liferay ServeResource

TL;DR 如何使用 java portlet ResourceRequest 从我的服务器下载文件?

我正在使用 GenericPortlet class 使用 Liferay 6.1.0 portlet 为我们的 CMS 构建本质上是一个浏览器。在 view.jsp 中,一旦用户打开了 CMS 资源,并且如果资源(HTML 页面)有指向 PDF 或图像的链接,这些链接将触发以下代码以请求下载资源(模仿正常行为):

view.jsp

<portlet:resourceURL var="ajaxResourceUrl"/>

$("#file-viewer").on("click", "a", function(e){
/* Prevent normal link navigation behavior*/
e.preventDefault();

/* Get the name of the file we want to download*/
var linkPath = $(this).attr("href");

/* Send the path to the server with resource request*/
$.ajax({
    method: 'POST',
    url: '<%= ajaxResourceUrl %>',
    data: {"action": "displayAttachment", "attachment": linkPath },
    dataType: "text",
    success: function(data) {
        console.log("success:" + data.substring(0, 10));
        if(data !== ""){
            if(linkPath.substring(linkPath.length - 4, linkPath.length) === ".pdf"){
                /* Resource is a PDF */


            } else {
                /* Resource is HTML */

                var html = data;
                var uri = "data:text/html," + encodeURIComponent(html);
                var newWindow = window.open(uri);

            }
        } else {
            $("#file-viewer").html("Error retrieving attachment \n" +     $("#file-viewer").html());

        }
    },
    error: function(err) {
        console.log("error" + err);
    }

});

});

在服务器上通过此方法处理:

CMSBrowser.java

public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException, IOException {

    String action = request.getParameter("action");

    // handler for multiple ajax actions
    if (new String("displayItem").equals(action)) {

        //other irrelevant code 

    } else if (new String("displayAttachment").equals(action)) {

        String filePath = request.getParameter("attachment");
        PortletPreferences portletPreferences = request.getPreferences();
        String rootPath = portletPreferences.getValue("rootPath", "");
        filePath = rootPath + filePath; 

        try {
                File f = new File(filePath);
                System.out.println("Trying to serve: " + filePath);

               String mimeType =    request.getPortletSession().getPortletContext().getMimeType(f.getName());

                response.setContentType(mimeType);
                response.addProperty(
                    HttpHeaders.CACHE_CONTROL, "max-age=3600, must-revalidate");

                OutputStream out = response.getPortletOutputStream();

                InputStream in = new FileInputStream(f);  // some InputStream


                    byte[] buffer = new byte[4096];
                    int len;

                    while ((len = in.read(buffer)) != -1) {
                        out.write(buffer, 0, len);
                    }

                    out.flush();
                    in.close();
                    out.close();

            } catch (IOException e) {
                _log.error("serveResource: Unable to write IO stream, IOException: ", e);
            }

    }  
}

我在 Eclipse、浏览器或服务器日志中没有收到任何错误。除了 ajax 成功方法 returns 和 "Error retrieving attachment" 之外没有任何反应,以防服务器没有返回任何内容。

我根据第 4 post 找到了 java 代码 here

具体来说,我正在尝试将此用于 download/open 在服务器上但不在 portlet/portal 或网络上可访问的新选项卡中的 PDF 和图像。此方法适用于 HTML 个页面。

我的问题是如何使用 java portlet ResourceRequest 从我的服务器下载文件?

(如果右括号或大括号不匹配,请忽略这一点,我不得不在此处删除大量代码 post;所有内容都在我的 [=54 中正确排列和关闭=]).

经过多次尝试类似的解决方案后,我尝试删除 view.jsp 中的 AJAX 函数并将其替换为:

    window.open('<%= ajaxResourceUrl %>&action=displayAttachment&attachment=' + linkPath);

这(不知何故)奏效了,现在它允许我在新选项卡中打开 HTML、PDF 和图像。